Javascript使用不同的参数链接相同的动画函数
我正在尝试为一条线设置动画,沿一条路径绘制两条线,一条接着另一条。基本上,它看起来就像画了一条线,停在一个点上,然后在其他地方画另一条线。到目前为止,我遇到过实现这一目标的承诺和回调,但作为一名javascript新手,这让人困惑 当前动画功能:Javascript使用不同的参数链接相同的动画函数,javascript,animation,promise,Javascript,Animation,Promise,我正在尝试为一条线设置动画,沿一条路径绘制两条线,一条接着另一条。基本上,它看起来就像画了一条线,停在一个点上,然后在其他地方画另一条线。到目前为止,我遇到过实现这一目标的承诺和回调,但作为一名javascript新手,这让人困惑 当前动画功能: /* * Animation function draws a line between every point */ var animate = function(p){ return new Promise(
/*
* 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}];
线需要遵循的路径就是点
和次点
我尝试了许多相似的解决方案,但微小的差异会导致我要么搞砸,要么不理解解决方案。我遇到的最大问题似乎是调用同一个动画函数,该动画函数需要在不同的参数上运行
如果没有此解决方案,请使用
animate(points);
animate(secondary_points);
线是在同一时间绘制的,但结果实际上是沿着路径随机放置的点,而不是平滑的线,我假设这两条线是同时运行的
我该如何着手解决这个问题,以便沿路径1绘制一条线,然后沿路径2绘制第二条线
这可能是一个简单的解决方案,但我已经和JS一起工作了3天,我的脑袋还在转,因为我已经习惯了一些我必须修复的旧代码的语法
多谢各位
编辑:
动画的完整流程如下所示:
我有一个php文件,其中包含2个画布,每个画布包含一个地图图像。php文件有两个
标记,其中一个通过drawPath(source,destination,true)
或drawPath(source,destination,false)
调用我正在编写动画的js脚本
drawPath函数使用布尔值确定要获取上下文的画布,然后通过查找路径并创建上文提到的点,然后使用animate()
绘制从点A到点B的路径。地图上有几处需要分开的线,这引发了我最初的问题。多亏了建议,我才能够解决这个问题,但现在我遇到了一个更大的问题
如果我需要从地图A上的A点到地图B上的B点,即
drawPath(源,地图A的端点,真)然后调用code>
drawPath(地图的起始点,目的地,false)代码>,这些线只在一张地图上绘制,它们类似于之前的1。随机和2。不完整/仅点
我假设这又是由于动画的缘故,因为它在静态绘制直线时起作用,而每个动画在单个贴图上从点A到点B时起作用
感谢您的帮助
编辑:
绘图路径()
处理这个问题的一个好方法是将线放入数组中,其中每个元素都是线的一组点。然后您可以调用reduce()
,依次触发每个承诺。如果您是javascript新手,需要一点习惯,但它基本上需要数组c
中的每个元素,在这种情况下,做一些事情,然后这些事情成为下一个a
。你以一个解决承诺开始整个过程,这将是最初的a
。承诺链将通过reduce
返回给您,您可以附加一个最终的,然后
知道整个事情何时完成
例如:
let canvas=document.getElementById('canvas')
让context=canvas.getContext('2d');
var animate=函数(p){
返回新承诺(函数(解析){
t=1;
var runAnimation=function(){
if(t({x:i+1,y:i+2}))
设points2=Array.from({length:200},({uu,i)=>({x:300-i,y:i+2}))
设points3=Array.from({length:200},({uu,i)=>({x:i*2,y:100+100*Math.sin(i/10)}))
//创建包含每个集合的数组
设集合=[点,点2,点3]
//使用reduce按顺序调用每个,每次都返回承诺
sets.reduce((a,c)=>a.then(()=>animate(c)),Promise.resolve()
。然后(()=>console.log(“完成”))
我不知道你是否偶然发现了,但它似乎回答了你的问题。我根据你的问题应用了答案。这个动画(点)。然后(动画(次点));
可能需要:动画(点)。然后(()=>动画(次点));
。你必须将函数引用传递给。然后()
以便稍后执行。您当时正在立即执行。@jfriend00此解决方案有效,谢谢!但是,现在我发现了一个新问题。我正在更新我的问题,以便按原样进行解释similar@jfriend00抱歉,编辑花了一点时间。首先,这个编辑看起来像是一个新的问题,与您第一次问的问题不同。第二f、 如果没有看到所有相关的代码,没有对应该发生的事情和您观察到发生的事情进行更完整的描述,我认为任何人都无法对此提供帮助。也许这属于另一个问题。@ChrisM,您理解正确。reduce
一开始让人困惑。它需要一个列表(sets
)对于每个项,调用一个带有两个参数的函数(这里为累加器调用a
,为当前调用调用c
)。该函数的返回值将成为下一次调用的a
。对于第一次调用,我们手动为其指定初始a
,这是承诺.resolve()
。第一个过程调用Promise.resolve()。然后(()=>animate(c))
其中“c”是列表中的第一个元素。这将生成一个新的Promise,它将成为下一个a
。它本质上使s成为一个很大的then()。then()
,等等,@ChrisM是的。用一个不包含承诺的例子可能更容易理解。reduce的经典用法是对一个数字数组求和。@ChrisM完全正确。[1,2,3]。reduce((a,c)=>a+c,0)
The=>表示
function drawPath(source, desti, flag) {
/*
* Define context
*/
//lower
if(!flag){
var c = document.getElementById("myCanvas");
context = c.getContext("2d");
//upper
} else {
var cUpr = document.getElementById("myCanvasUpr");
context = cUpr.getContext("2d");
}
/*
* Clear the variables
*/
points = [];
secondary_points = [];
vertices = [];
secondary_vertices = [];
t = 1;
done = false;
//check for invalid locations
if (source != "" && desti != "") {
context.lineCap = 'round';
context.beginPath();
/*
* Get the coordinates from source and destination strings
*/
var src = dict[source];
var dst = dict[desti];
/*
* Get the point number of the point on the path that the source and destination connect to
*/
var begin = point_num[source];
var finish = point_num[desti];
/*
* Draw the green and red starting/ending circles (green is start, red is end)
*/
context.beginPath();
context.arc(src[0], src[1], 8, 0, 2 * Math.PI);
context.fillStyle = 'green';
context.fill();
context.beginPath();
context.arc(dst[0], dst[1], 6, 0, 2 * Math.PI);
context.fillStyle = 'red';
context.fill();
/*
* Call the function that draws the entire path
*/
draw_segments(begin, finish, src, dst, flag);
//window.alert(JSON.stringify(vertices, null, 4))
/*
* Edit what the line looks like
*/
context.lineWidth = 5;
context.strokeStyle = "#ff0000";
context.stroke();
}
}