我正在学习用JavaScript编程。我正在编写一些带有定时鼠标动画的程序。我即将添加一些代码,以绘制鼠标路径。
这将是一个接收mousemove事件的东西,每次鼠标移动时在Canvas上绘制新的路径线。随着时间的推移,该路径将变得更加透明,直到消失。当然,新路径总是不透明的,因此存在连续的运动。
我想出了一种方法,可以只使用requestanimationframe来完成这项工作。基本上,每当发生新的mousemove事件时,我将该鼠标路径坐标添加到名为mousePathArray的对象数组中。该对象将携带路径坐标和“animationStage”计数器。该计数器基本上将确定在“动画”的那个阶段路径有多透明。(后期阶段将意味着更透明。)
然后,每个动画帧都会调用一个函数,该函数将遍历数组中的所有对象,并根据它们的坐标和animationStage计数器绘制线条,将计数器增加1,并在animationStage计数器达到结束数字(可能为50或其他数字)时删除数组对象。
虽然可以做到这一切,但听起来与所有这些相比,只需引入一个setInterval函数,每次鼠标移动时都会被调用,会更容易些。
那么这样做值得吗?通过不使用setInterval和rAF,在JS中进行良好的实践,这可能会更快一些或更好一些?
在写下所有这些内容之后,我实际上编写了我上面谈论过的仅使用rAF的代码。它太长了无法粘贴到这里,但规则需要它。在jsfiddle上是这样的:http://jsfiddle.net/06f7zefn/2/
(我知道存在很多低效率和可能可怕的编码实践,但请容忍我,我才5天学习这个!与其在每个帧上调用animate(),我可以创建一个isDrawing?布尔值,以及只需进行一次ctx.moveTo(),其余均为LineTo(),而无需在每次迭代中都调用moveTo(),因为一个点从另一个点开始。)
如果我能传达我所谈论的主要思想,那就是我在询问您的意见的地方。在这里,是否最好使用setInterval或setTimeout替代将与时间相关的所有内容起源于rAF调用?
var canvas = document.createElement('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.body.appendChild(canvas);
var ctx = canvas.getContext('2d');
var currentPosX, currentPosY, prevPosX, prevPosY;
var mousePathArray = [];
canvas.addEventListener ('mousemove', mouseOp);
function mouseOp (mouseEvent) {
prevPosX = currentPosX;
prevPosY = currentPosY;
currentPosX = mouseEvent.clientX;
currentPosY = mouseEvent.clientY;
mousePathArray.push( {
x1: currentPosX,
x2: prevPosX,
y1: currentPosY,
y2: prevPosY,
animStage: 0
});
}
function animate () {
var anims = mousePathArray.length;
if (anims!=0) {
for (i=0; i<anims; i++) {
if (mousePathArray[i].animStage == 20) {
mousePathArray.splice(i, 1);
i--;
anims--;
continue;
}
drawLine(mousePathArray[i].x1, mousePathArray[i].x2, mousePathArray[i].y1, mousePathArray[i].y2, 1 - (mousePathArray[i].animStage * 0.05));
mousePathArray[i].animStage ++;
}
}
}
function drawLine (x1, x2, y1, y2, alpha) {
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.strokeStyle = "rgba(150, 20, 150," + alpha +")";
ctx.stroke();
}
animloop();
function animloop(){
window.requestAnimationFrame(animloop);
gameLoop();
}
function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
animate();
}