Javascript 在画布中绘制动画曲线

Javascript 在画布中绘制动画曲线,javascript,html,canvas,Javascript,Html,Canvas,几天前,我来到stackoverflow,询问如何将箭头缓慢地画入画布。没有人能给我正确的答案。。。所以我希望这能帮助一些人 基本上,我想在地图上显示从一个国家到另一个国家的入侵过程。要做到这一点,我应该用画布画一个箭头,从A国移动到B国,但不是一个固定的箭头。。。逐渐生长的箭 下面的代码绘制了一个箭头,但不是渐进的。因此,我需要像CSS动画一样绘制这条曲线,并进行5s过渡 函数绘制曲线(ctx、x0、y0、x1、y1、x2、y2){ ctx.beginPath(); ctx.moveTo(x

几天前,我来到stackoverflow,询问如何将箭头缓慢地画入画布。没有人能给我正确的答案。。。所以我希望这能帮助一些人

基本上,我想在地图上显示从一个国家到另一个国家的入侵过程。要做到这一点,我应该用画布画一个箭头,从A国移动到B国,但不是一个固定的箭头。。。逐渐生长的箭

下面的代码绘制了一个箭头,但不是渐进的。因此,我需要像CSS动画一样绘制这条曲线,并进行5s过渡

函数绘制曲线(ctx、x0、y0、x1、y1、x2、y2){
ctx.beginPath();
ctx.moveTo(x0,y0);
ctx.二次曲线(x1,y1,x2,y2);
ctx.stroke();
ctx.closePath();
}
var docCanvas=document.getElementById('canvas');
var ctx=docCanvas.getContext('2d');
拉深曲线(ctx,0,100,150,-50,300,100)

经过一番挖掘,我找到了这个解决方案,它给了我想要的一切

基本上
drawBezierSplit()
允许您绘制一段二次bezier曲线

这一切都归功于帕特里克·加尔布雷斯

/**
*为贝塞尔曲线设置动画
* 
*@param ctx要绘制到的画布上下文
*@param x0起点的x坐标
*@param y0起点的y坐标
*@param x1控制点的x坐标
*@param y1控制点的y坐标
*@param x2终点的x坐标
*@param y2终点的y坐标
*@param duration持续时间以毫秒为单位的持续时间
*/
函数动画绘制(ctx、x0、y0、x1、y1、x2、y2、持续时间){
var start=null;
var step=函数animatePathDrawingStep(时间戳){
如果(开始===null)
开始=时间戳;
var delta=时间戳-开始,
进度=数学最小值(增量/持续时间,1);
//透明帆布
clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
//绘制曲线
拉丝比塞尔分裂(ctx,x0,y0,x1,y1,x2,y2,0,进度);
如果(进度<1){
window.requestAnimationFrame(步骤);
}
};
window.requestAnimationFrame(步骤);
}
/**
*绘制分割的贝塞尔曲线
* 
*@param ctx要绘制到的画布上下文
*@param x0起点的x坐标
*@param y0起点的y坐标
*@param x1控制点的x坐标
*@param y1控制点的y坐标
*@param x2终点的x坐标
*@param y2终点的y坐标
*@param t0从0.0到1.0的分割贝塞尔的起始比率
*@param t1从0.0到1.0的分割贝塞尔的起始比率
*/
函数drawBezierSplit(ctx、x0、y0、x1、y1、x2、y2、t0、t1){
ctx.beginPath();
如果(0.0==t0&&t1==1.0){
ctx.moveTo(x0,y0);
ctx.二次曲线(x1,y1,x2,y2);
}否则如果(t0!=t1){
变量t00=t0*t0,
t01=1.0-t0,
t02=t01*t01,
t03=2.0*t0*t01;
变量nx0=t02*x0+t03*x1+t00*x2,
ny0=t02*y0+t03*y1+t00*y2;
t00=t1*t1;
t01=1.0-t1;
t02=t01*t01;
t03=2.0*t1*t01;
变量nx2=t02*x0+t03*x1+t00*x2,
ny2=t02*y0+t03*y1+t00*y2;
var nx1=lerp(lerp(x0,x1,t0),lerp(x1,x2,t0),t1),
ny1=lerp(lerp(y0,y1,t0),lerp(y1,y2,t0),t1);
ctx.moveTo(nx0,ny0);
四次曲线(nx1,ny1,nx2,ny2);
}
ctx.stroke();
ctx.closePath();
}
/**
*在两个数字之间线性插值
*/
功能lerp(v0、v1、t){
返回(1.0-t)*v0+t*v1;
}
var docCanvas=document.getElementById('canvas');
var ctx=docCanvas.getContext('2d');
动画绘制(ctx,0,100,150,-50,300,100,5000)