我们有一个点数组,我们想通过它在HTML5画布上绘制一条二次曲线,但我们想慢慢绘制曲线,而不是一次绘制。有点像回放曲线的绘制。
原始曲线:http://jsfiddle.net/NWBV4/12/
曲线回放:http://jsfiddle.net/NWBV4/15/
在曲线回放中,如果我们将SEGMENT_PER_POINTS更改为非常大的值(例如,1000),它将在一次拍摄中完美绘制。
但正如你所知,对于较小的数字,曲线的回放存在差距。
关于我们如何解决这个问题,有什么线索吗?我们被卡住了!
您应该在绘图代码中添加一个睡眠基元。然而,在javascript中,这不是使用sleep或wait原语,而是使用setInterval
或setTimeout
以事件导向的方式实现的。如图所示:
var sec = 1000; // milliseconds
var totalDrawingTime = 5*sec;
var numPointsToDraw = [calculate this];
var waitTimePerPoint = totalDrawingTime/numPointsToDraw;
function slowlyDrawCurve(...) {
var x = ...;
function drawNextPointAndWait() {
x += ...;
if (x < MAX_CANVAS_SIZE) {
y = f(x);
point = [x,y];
dispatch_to_canvas_function(point);
setTimeout(helper, waitTimePerPoint);
}
}
drawNextPointAndWait();
}
编辑
此处演示:http://jsfiddle.net/eJVnU/4/
这其实更有意思。也就是说,如果你以几毫秒的间隔绘制(1000点意味着每次更新1毫秒!),你需要小心如何处理javascript的计时器。使用setTimeout
调度的javascript事件可能在几毫秒或更长时间内不会触发,从而使其不可靠!因此,我所做的是计算出每个片段应该在何时完成。如果我们比计划提前了几毫秒以上,我们会执行setTimeout
,但如果我们在其他方面落后于计划,我们会直接对片段绘制例程执行递归调用,从而缩短事件处理系统。这也确保了绘制对人眼来说是平滑的,只要线段的长度大致相等。
(如果你想更顺利地完成,你可以计算出绘制的线段的长度,保持绘制的弧长的总和,并将其除以某个固定的恒定速率arclength_per_second
,以计算出应该花多长时间。)