[英]Javascript improve canvas performance
我创建了一个背景画布,可绘制约300个对象。现在,当我移动鼠标时,它会滞后很多时间。 可能不是因为画布无法绘制300个对象?
我已经进行了一些有关优化的研究,例如仅使用整数,因此抗混叠将更少。
<script>
var stars = [];
var starCount = 500;
var starColors = ["#125A89", "#409897", "#042B44", "#125987"];
//Setup canvas
var canvas = document.getElementById("background");
var ctx = canvas.getContext("2d");
//Initialize all the measurements
function initialize() {
var backgroundWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var backgroundHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
document.getElementById("myCanvas").setAttribute('width', backgroundWidth);
document.getElementById("myCanvas").setAttribute('height', backgroundHeight);
//Start the background and draw it
createStars(starCount);
drawBackground();
}
//Create the star objects in a array
function createStars(starCount) {
stars = [];
for (var i = 0; i < starCount; i ++) {
var star = {
size: getRandomInt(1, 3),
Yspeed: getRandomInt(4, 10),
Xpos: getRandomInt(0, canvas.width),
Ypos: getRandomInt(0, canvas.height),
color: starColors[getRandomInt(0, starColors.length)]
}
stars.push(star);
}
}
//Generate random number
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function drawBackground() {
//Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
//Draw background
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#000000";
ctx.fill();
//Draw al the stars from the array
for (var i = 0; i < stars.length; i ++) {
var star = stars[i];
ctx.beginPath();
ctx.rect(star.Xpos, star.Ypos, star.size, star.size);
if (ctx.fillStyle != star.color) ctx.fillStyle = star.color;
ctx.fill();
if (star.Ypos + star.size > canvas.height) star.Ypos = -star.size;
else star.Ypos += star.Yspeed;
}
//Call the next draw cycle
setTimeout(function() {
window.requestAnimationFrame(drawBackground);
}, 1000/60);
}
</script>
初始化函数称为onresize
和onload
,我可以做一些更改来优化代码吗? 还是我只是在推动极限。
这里对requestAnimationFrame的工作方式有些误解。
您无需尝试以每秒60次的速度强制对requestAnimationFrame的调用(re:1000/60)。 那是自动发生的。
window.requestAnimationFrame()方法告诉浏览器您希望执行动画,并请求浏览器在下一次重绘之前调用指定的函数来更新动画。 该方法将回调作为要在重绘之前调用的参数。
回调次数通常为每秒60次,但按照W3C的建议,通常将与大多数Web浏览器中的显示刷新率匹配。
-window.requestAnimationFrame() MDN
您在这里真正要做的是每1000/60调用一次超时,然后尝试调用drawBackground
。 由于超时不可靠,因此会产生斜坡效应,并导致您观察到滞后问题。
从您的代码中删除setTimeout,而只需使用
window.requestAnimationFrame(drawBackground);
除了使用timeOut之外,在其运行requestAnimationFrame时多次调用drawBackground
也不是一个好主意-尤其是考虑到它处理的数据不在函数范围内,这意味着无论如何更新它都使用stars数组。 使用一个标志来确保动画还没有开始,以防止多次调用它来初始化。
var animationRunning = false;
function initialize() {
//... existing code
if(!animationRunning){
drawBackground();
animationRunning = true;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.