Html 在画布上为绘制弧线设置动画

Html 在画布上为绘制弧线设置动画,html,canvas,html5-canvas,Html,Canvas,Html5 Canvas,我正在尝试实现一个在画布上绘制arcTo线的动画。例如,对于直线,动画如下所示 c = canvas.getContext("2d"); width = window.innerWidth; height = window.innerHeight; complete = false var percent = 1 function drawEdge(x1, y1, x2, y2, color){ c.beginPath(); c.lineWidth = 10; c.strokeStyl

我正在尝试实现一个在画布上绘制arcTo线的动画。例如,对于直线,动画如下所示

c = canvas.getContext("2d");

width = window.innerWidth;
height = window.innerHeight;
complete = false
var percent = 1

function drawEdge(x1, y1, x2, y2, color){
 c.beginPath();
 c.lineWidth = 10;
 c.strokeStyle = color;
 c.moveTo(x1, y1);
 c.lineTo(x2, y2);
 c.stroke();
 c.closePath();
}

function getPosition(x1, y1, x2, y2, percentageBetweenPoints){
 let xPosition = x1 + (x2 - x1) * (percentageBetweenPoints / 100);
 let yPosition = y1 + (y2 - y1) * (percentageBetweenPoints / 100);

 const position = {
     x: xPosition,
     y: yPosition,
 }
 return position
}

function drawLine(){
 if (!complete){
     requestAnimationFrame(drawLine);
 }

 if (percent >= 100){
     complete = true;
     percent = 100;
 } else{
     percent = percent + 1;
 }

 position = getPosition(300,300,1000,300,percent);
 c.clearRect(0, 0 , width, height);
 drawEdge(300,300,position.x,position.y, "black");

}

drawLine()


这将创建在屏幕上绘制直线的动画。然而,我在为arcTo线做同样的事情时遇到了麻烦。有什么方法可以实现这一点吗?

您正在寻找类似的东西吗

设ctx=canvas.getContext'2d'; ctx.textAlign=中心; ctx.textBaseline=中间; ctx.font='bold 18px Arial'; 请求动画框架绘制; 函数图{ t=t%5e3/5e3; ctx.clearRect0,0,canvas.width,canvas.height; ctx.beginPath; ctx.arccanvas.width/2,canvas.height/2,50,0,t*2*Math.PI; ctx.stroke; ctx.fillTextt*100.toFixed0,canvas.width/2,canvas.height/2; 请求动画框架绘制; } 黑客还是不黑客? 有两种方法可以做到这一点

计算每条线段的起点、终点和长度、起点、终点角度、方向CW或CCW以及每条弧段的中心。基本上重复了50行左右的数学和逻辑代码,使arcTo成为如此有用的渲染函数

您可以从中获得有关如何实现完整解决方案的详细信息

将ctx.lineDash与长破折号和长空格一起使用。使用ctx.lineDashOffset随时间移动短划线,以显示长度不断增长的线条。请参见演示。破折号偏移值是反向的,从“最大长度”开始,到“零”结束

注意:这种方法有一个问题。你不知道这条线的长度,因此你不知道这条线需要多长时间才能完成。你可以估计一下。要知道这条线的长度,你必须把这附近的所有计算都做好

黑客 因为第二种方法最容易实现,并且涵盖了大多数需求,所以我将演示该方法

不用多说,它为ctx.arcTo创建的路径设置动画 另一个好处是,它将为使用ctx.stroke渲染的任何路径设置动画

requestAnimationFramemainLoop; //线是在单位空间中定义的。 //原点位于画布的中心,-1,-1左上角,1,1右下角 //单元框为方形,将按比例缩放以适应画布大小。 //注意:我没有使用ctx.setTransform更好地突出显示缩放的内容和未缩放的内容。 const ctx=canvas.getContext2d; 变量w,h,w2,h2;//帆布尺寸和半尺寸 变量linePos;//当前破折号偏移量 var刻度;//帆布秤 常数线宽=0.05;//单位 常量行样式=000;//黑色 常数线速度=1;//单位为每秒 常数最大线长度=9;//单位约为 常数半径=0.08//弧半径单位 [0.5、0.95、0.0、0.5、[0.0 0、0.5、0.95、0.0、0.5、[0.0 0、0.0 0、0.5、-0.0、0.95、0.95、0.95、0.95、0.95、0.95、0.5、-0.5、0.5、0.5、0.5、0.5、[0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.5、0.2]]; 函数sizeCanvas{ w2=w=canvas.width=innerWidth/2; h2=h=canvas.height=innerHeight/2; 标度=Math.minw2,h2; 复位线; } 函数addToPathshape{ 变量p1,p2; 对于形状的p2{ !p2.长度? ctx.closePath: p1?ctx.arcTop1[0]*刻度+w2,p1[1]*刻度+h2,p2[0]*刻度+w2,p2[1]*刻度+h2,半径*刻度: ctx.lineTop2[0]*比例+w2,p2[1]*比例+h2 ; p1=p2; } } 函数重置行{ ctx.setLineDash[最大线长度*刻度,最大线长度*刻度]; linePos=最大线长度*刻度; ctx.lineWidth=线宽*比例; ctx.lineJoin=ctx.lineCap=round; } 函数主循环{ 如果w!==内部宽度| | h!==内部高度{sizeCanvas} else{ctx.clearRect0,0,w,h} ctx.beginPath; addToPathSHAPE; ctx.lineDashOffset=linePos-=LINE_速度*刻度*1/60; ctx.stroke; 如果linePos