javascript - Javascript用不同的参数链接相同的动画函数
问题描述
我正在尝试沿一条路径为一条线设置两条线,一条线然后另一条线。基本上它看起来就像画一条线,停在一个点,然后另一条线在其他地方画。到目前为止,我遇到了实现这一目标的承诺和回调,但作为一个 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
我已经在 SO 上尝试了许多相似的解决方案,但小的差异会导致我搞砸或不理解解决方案。我似乎遇到的最大问题是调用 SAME animate 函数,该 animate 函数需要在不同的参数上运行。
如果没有这个解决方案,使用
animate(points);
animate(secondary_points);
线条是同时绘制的,但结果实际上只是沿路径随机放置点而不是平滑线,我假设是因为两者同时运行。
我将如何解决这个问题,以便沿着 path1 绘制一条线,然后沿着 path2 绘制第二条线?
这可能是一个简单的解决方案,但我已经使用 JS 工作了 3 天,但我的头脑仍然无法适应我必须修复的旧代码的一些语法
谢谢
编辑:
动画的完整流程如下:
我有一个 php 文件,其中包含 2 个画布,每个画布都包含一张地图的图像。php 文件有几个<script/>
标签,其中一个调用我正在通过drawPath(source,destination,true)
或编写动画的 js 脚本drawPath(source,destination,false)
drawPath 函数使用布尔值来确定要获取哪个画布的上下文,然后通过查找路径并创建points
上述路径在从点 A 到点 B 的路径上绘制,然后使用animate()
. 地图中有几个中断需要单独的行,这引发了我最初的问题。由于建议,我能够解决这个问题,但现在我遇到了一个更大的问题。
如果我需要从地图A上的A点到地图B上的B点,即
drawPath(source, end_point_of_map_A, true);
被称为 then
drawPath(start_point_of_map_B, destination, false);
,这些线只在一张地图上绘制,它们与之前相似,它们是 1. 随机和 2. 不完整/仅点
我假设这又是由于动画造成的,因为它仅在静态绘制线条时起作用,并且每个动画在单个地图上从点 A 到 B 时起作用
任何帮助表示赞赏!
编辑:
绘图路径()
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();
}
}
解决方案
处理此问题的一个好方法是将您的线条放入一个数组中,其中每个元素都是线条的一组点。然后你可以调用reduce()
它依次触发每个承诺。reduce()
如果您是 javascript 新手,需要一点时间来适应,但c
在这种情况下,它基本上需要数组的每个元素,做某事,然后某事成为下一个a
. 你从一个 resolve promise 开始整个事情,这将是 initial 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>
推荐阅读
- c# - Excel VBA - 具有多个参数的 Shell 可执行文件
- java - 如何在不复制拓扑的情况下测试 Kafka Stream 应用程序?使用 TopologyTestDriver?
- python-2.7 - 什么定义了“完整”的 Luigi 任务?
- searchkick - Searchkick 重新索引,但除非给出完整的单词,否则搜索不起作用
- python - TypeError: ArrayType(DoubleType,true) 不能接受对象 u'..'
- html - div 布局没有得到与预期相同的结果
- node.js - NodeJS - 从 S3 读取文件到 Lambda 中的 /tmp 文件夹
- powershell - 模块中的变量不显示
- python-3.x - 更快的方法:在熊猫数据框中分配 vs 附加
- microsoft-graph-api - 如何使用 MS Graph API 从存档邮箱中获取消息