【发布时间】:2016-08-10 12:20:13
【问题描述】:
我编写了包含两个数组的代码,这两个数组都包含一个四角形状的坐标(实际上是一个起始帧和一个结束帧)、一个画布 ID 和一个时间值。然后该函数计算每个角的 dX 和 dY 并使用 window.performance.now() 创建时间戳。然后,在每个requestAnimationFrame() 上,它通过使用 dX、dY、旧时间戳、新时间戳和函数调用的时间值来计算坐标应该是什么。它看起来像这样:
function doAnim(cv, startFrame, endFrame, animTime)
{
this.canvas = document.getElementById(cv);
this.ctx = this.canvas.getContext('2d');
if(startFrame.length != endFrame.length)
{
return('Error: Keyframe arrays do not match in length');
};
this.animChange = new Array();
for(i=1;i<=startFrame.length;i++)
{
var a = startFrame[i];
var b = endFrame[i]
var c = b - a;
this.animChange[i] = c;
}
this.timerStart = window.performance.now();
function draw()
{
this.requestAnimationFrame(draw, cv);
this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
this.currentFrame = new Array();
for(i=1;i<=startFrame.length;i++)
{
this.currentFrame[i] = startFrame[i]+(this.animChange[i]*((window.performance.now()-this.timerStart)/animTime));
}
if((window.performance.now()-this.timerStart)>=animTime)
{
this.ctx.beginPath()
this.ctx.moveTo(endFrame[1], endFrame[2]);
this.ctx.lineTo(endFrame[3], endFrame[4]);
this.ctx.lineTo(endFrame[5], endFrame[6]);
this.ctx.lineTo(endFrame[7], endFrame[8]);
this.ctx.fill();
return;
}
else
{
this.ctx.beginPath()
this.ctx.moveTo(this.currentFrame[1], this.currentFrame[2]);
this.ctx.lineTo(this.currentFrame[3], this.currentFrame[4]);
this.ctx.lineTo(this.currentFrame[5], this.currentFrame[6]);
this.ctx.lineTo(this.currentFrame[7], this.currentFrame[8]);
this.ctx.fill();
}
}
draw();
}
目标是同时发生多个对象动画。我采用了整个坐标的方法,因为我希望对象看起来好像它们来自地平线,创建一个假的 3D 透视效果(所有对象的起始帧都是画布中心的一个点),并且我不想扭曲对象的纹理。
嗯,它适用于单个动画,但如果我尝试在第一个动画运行时在完全不同的画布上开始一个新动画,那么第一个动画将停止在其轨道上。
正如你从我的 JS 中看到的那样,我尝试通过无偿使用 this 来解决这个问题(我还不完全理解 this 的工作原理,我读过的每一个解释都让我更加难忘困惑),但它没有奏效。我还尝试了一种可怕的方法,将所有函数自己的变量存储在一个全局数组中(函数第一次运行时,所有变量都放在条目 1-30 中,第二次它们放在 31-60 中,等等)。不出所料,这也不起作用。
Here is a JSFiddle so you can see this scenario for yourself and play with my code.我正式没有想法了。任何帮助将不胜感激。
【问题讨论】:
-
这个元素在哪里 document.getElementById(cv);
-
cv 是画布的 ID,在 doAnim 函数的第一个参数中定义。我将在我的测试设置中运行的函数将是
doAnim('canvas1', anim_frame1, anim_frame2, 1000)在 ID 为“canvas1”的画布中执行 1 秒动画。 -
查看之前的Q&A,它展示了如何在单个 requestAnimationFrame 循环下运行多个动画。
标签: javascript html animation canvas