用不同的参数将相同的动画函数链接在一起的JavaScript

时间:2018-07-19 21:09:43

标签: javascript animation promise

我正在尝试沿一条路径的两条线设置动画,然后是另一条。基本上看起来像是画一条线,停在一个点,然后画另一条线。到目前为止,我已经碰到了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}];

直线需要遵循的路径只是pointssecondary_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)

编写动画的js脚本。

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);

1 个答案:

答案 0 :(得分:2)

处理此问题的一种好方法是将线放入一个数组中,其中每个元素都是线的一组点。然后,您可以调用reduce()依次触发每个承诺。如果您不熟悉javascript,reduce()会有点适应,但是在这种情况下,它基本上会占用数组c的每个元素,执行某些操作,然后某些操作成为下一个a 。您从一个完整的解决承诺开始,这个承诺就是最初的areduce将返回诺言链,您可以添加到最终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>