我正在尝试沿一条路径的两条线设置动画,然后是另一条。基本上看起来像是画一条线,停在一个点,然后画另一条线。到目前为止,我已经碰到了Promise和callbacks来实现这一目标,但是作为javascript新手,这很令人困惑
当前动画功能:
/*
* Animation function draws a line between every point
*/
var animate = function(p){
return new Promise(function(resolve) {
t = 1;
var runAnimation = function(){
if(t<p.length-1){
context.beginPath();
context.moveTo(p[t-1].x,p[t-1].y);
context.lineTo(p[t].x,p[t].y);
context.stroke();
t++;
requestAnimationFrame(function(){runAnimation()});
} else {
resolve()
}
};
runAnimation();
});
}
当前对动画功能的调用:
animate(points).then(animate(secondary_points));
这些点类似于:
var points = [{x:100, y:200}];
直线需要遵循的路径只是points
和secondary_points
内的多个坐标
我曾经尝试过许多类似的解决方案,但是细微的差异会导致我搞砸或者不理解该解决方案。我似乎遇到的最大问题是调用SAME动画函数,该动画函数需要在不同的参数上运行。
在没有此解决方案的情况下,使用
animate(points);
animate(secondary_points);
这些线是在同一时间绘制的,但实际上实际上是沿路径随机放置的点,而不是平滑的线,我想是因为两者同时运行。
我该如何解决这个问题,以便沿着path1绘制一条线,然后沿着path2绘制第二条线?
这可能是一个简单的解决方案,但是Ive与JS一起工作了3天,但我的头脑仍然从适应Ive必须修复的旧代码的语法中旋转
谢谢
编辑:
动画的完整流程如下:
我有一个包含2个画布的php文件,每个画布包含一张地图图像。 php文件具有几个<script/>
标签,其中一个调用了我通过drawPath(source,destination,true)
或drawPath(source,destination,false)
drawPath函数使用布尔值确定要为其获取上下文的画布,然后通过查找路径并创建上述points
来绘制从A点到B点的路径,然后使用{ {1}}。地图中有几个中断需要分开的行,这提示了我最初的问题。由于提出了建议,我得以解决此问题,但是现在我遇到了一个更大的问题。
如果我需要从地图A上的A点转到地图B上的B点,即
然后调用 animate()
drawPath(source, end_point_of_map_A, true);
中,线条仅在一张地图上绘制,与之前的相似之处是1.随机和2.不完整/仅点
我认为这又是由于动画引起的,因为它仅在静态绘制线条时起作用,并且每个动画在一张地图上从A点到B点都可以起作用
感谢您的帮助!
编辑:
DrawPath()
drawPath(start_point_of_map_B, destination, false);
答案 0 :(得分:2)
处理此问题的一种好方法是将线放入一个数组中,其中每个元素都是线的一组点。然后,您可以调用reduce()
依次触发每个承诺。如果您不熟悉javascript,reduce()
会有点适应,但是在这种情况下,它基本上会占用数组c
的每个元素,执行某些操作,然后某些操作成为下一个a
。您从一个完整的解决承诺开始,这个承诺就是最初的a
。 reduce
将返回诺言链,您可以添加到最终then
上,以了解整件事何时完成。
例如:
let canvas = document.getElementById('canvas')
let context = canvas.getContext('2d');
var animate = function(p){
return new Promise(function(resolve) {
t = 1;
var runAnimation = function(){
if(t<p.length-1){
context.beginPath();
context.moveTo(p[t-1].x,p[t-1].y);
context.lineTo(p[t].x,p[t].y);
context.stroke();
t++;
requestAnimationFrame(function(){runAnimation()});
} else {
resolve()
}
};
runAnimation();
});
}
// make some points:
let points = Array.from({length: 200}, (_,i) => ({x:i+1, y:i+2}))
let points2 = Array.from({length: 200}, (_,i) => ({x:300-i, y:i+2}))
let points3 = Array.from({length: 200}, (_,i) => ({x:i*2, y:100+100*Math.sin(i/10)}))
// create an array holding each set
let sets = [points, points2, points3]
// use reduce to call each in sequence returning the promise each time
sets.reduce((a, c) => a.then(() => animate(c)), Promise.resolve())
.then(() => console.log("done"))
<canvas id="canvas" height="300" width="500"></canvas>