我尝试使用画布开发一个图形绘制网络应用程序,其中包括线条动画,如下所示:
function animateLine(x1, y1, x2, y2) {
ctx.lineWidth = 5;
const nrFrames = 30;
const dy = y2 - y1;
const dx = x2 - x1;
const incx = dx / nrFrames;
const incy = dy / nrFrames;
let tmpx = x1, tmpy = y1;
ctx.strokeStyle = 'rgba(11, 158, 131, 0.4)';
for (let i = 0; i < nrFrames; i++) {
setTimeout(() => {
tmpx += incx;
tmpy += incy;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(tmpx, tmpy);
ctx.stroke();
}, i * 16);
}
}
但也适用于这样的圆圈:
class Circle {
constructor(x, y, radius, name) {
this.x = x;
this.y = y;
this.radius = radius;
this.name = name;
}
draw() {
ctx.strokeStyle = 'black';
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.stroke();
ctx.fillStyle = 'rgb(110, 255, 255)';
ctx.fill();
ctx.fillStyle = 'black';
ctx.fillText(this.name, this.x, this.y);
}
}
考虑到共享上下文以及函数必须异步运行的事实,笔划永远不会具有预期的颜色。
我发现我可以在每个笔划的正上方添加中风样式 = '...',但我不认为这是最好的解决方案,因为有很多异步函数,你永远无法保证。
笼统地说:使用相同上下文的异步函数的不同风格需求的问题是如何管理的?
基本上有两种选择:同步绘制某些内容的不同部分或在每个
strokeStyle = ...
语句之前实际放置 .stroke()
。
如果要同步代码,则需要一个集中的
draw()
函数,轮流调用所有依赖的 draw()
函数。这可确保它们不会相互干扰(例如更改颜色)。
同步肯定会更复杂一些,但代码最终会更干净。对于您的动画,这意味着您不能再以这种方式使用
setTimeout
。