Նախ, եթե ցանկանում եք մի բան, որը դանդաղ չէ, խուսափեք jQuery-ի բոլոր հնարավոր զանգերից:
Ահա, թե ինչպես ես կվերագրեի (իսկապես արագ) ձեր կոդը.
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
var canvas = document.getElementById('canvas-test');
canvas.height = 500;
canvas.width = 500;
var context = canvas.getContext('2d');
// in this example, the fillstyle is always the same. no need to change it at every loop
context.fillStyle = "#FF0000";
var balls = [];
var ballcanvas = [];
var ballctx = [];
// create 30 balls in canvases
var eDivBody = document.getElementById('divbody');
for (var i = 0; i < 30; i++){
balls[i] = {
x : 250,
y : 100 + i * 2,
dx : 3, // direction
};
// create the canvas
var eBall = document.createElement('canvas');
eBall.id = 'ballcanvas' + i;
eBall.width = 75;
eBall.height = 75;
eDivBody.appendChild(eBall);
// some css
// no need for jQuery
eBall.style.position = "absolute";
eBall.style.left = balls[i].x + "px";
eBall.style.top = balls[i].y + "px";
eBall.style.backgroundColor = "#000000";
// associate the element to the ball, no need to go threw the DOM after
balls[i].element = eBall;
}
var ball_test = {
x : 250,
y : 300,
dx : 3 // direction
};
function loop(ball_test, balls, canvas, context, ballcanvas, ballctx){
//change of direction on the sides
if (ball_test.x > 400 || ball_test.x < 100)
ball_test.dx *= -1;
// movement
ball_test.x += ball_test.dx;
// the same for balls in canvases
// never use array.legth in a loop condition. put it in a variable then compare.
for (var i = 0, j = balls.length; i < j; i++){
// balls are following the test ball, no need to re-check the bounds
// we take the test ball direction
balls[i].dx = ball_test.dx;
//movement
balls[i].x += balls[i].dx;
// change left style - No need for jQuery
balls[i].element.style.left = balls[i].x + "px";
}
// display ball_test
displayBallTest(ball_test, canvas, context);
// Prefer the use of requestAnimationFrame
requestAnimFrame(function(){
loop(ball_test, balls, canvas, context, ballcanvas, ballctx);
});
};
// no need to recalculate Math.PI * 2 for every loop.
// do it just the first time then use the value
var pi2 = Math.PI * 2;
function displayBallTest(ball, canvas, context){
// clear canvas
// you don't need to clear all the canvas, just the zone where you now the ball is.
// must need some calculation to be the most efficient possible
context.clearRect(ball.x - 50 , ball.y - 50, 100, 100);
context.beginPath();
context.arc(ball.x, ball.y, 40, 0, pi2 );
context.fill();
};
// start main loop
loop(ball_test, balls, canvas, context, ballcanvas, ballctx);
Ես մեկնաբանեցի կոդը, բայց ահա թե ինչ արեցի.
- լիովին խուսափել jQuery-ից: Կարիք չկա, բացառությամբ միգուցե պատրաստի, եթե որոշեք ձեր սցենարը չդնել բովանդակության վերջում
- օգտագործելով requestAnimationFrame-ը, երբ հնարավոր է
- խուսափելով արժեքների վերահաշվարկից կամ վերակայումից, երբ դրանք գլոբալ են (Math.PI*2, context.fillStyle…)
- խուսափելով .length if for loop-ի օգտագործումից
Բայց ես կարծում եմ, որ ձեր խնդիրը գալիս է նրանից, որ դուք ցանկանում եք տեղափոխել 30 կտավի տարրեր՝ դրանց բովանդակությունը հիմնական կտավի մեջ նկարելու փոխարեն: Հայտնի է, որ iOS-ն արագ է, երբ դուք օգտագործում եք կտավ գծագրություն: Ինձ համար ձեր կատարողական խնդիրները կլուծվեն, եթե դուք ընտրեք նկարել հիմնական կտավի վրա DOM տարրերը տեղափոխելու փոխարեն:
25.07.2012