如何让箭头穿过canvas?

How to make an arrow move across the canvas?

我需要按以下顺序为箭头 1-5 设置动画(请参阅附图)

例如:箭头 1 将从 点 1 移动到 点 2 然后 箭头 2 将从 点 2 移动到 点 3 ... 直到箭头 5.

请看: 我只能通过 JQuery 和 HTML5 canvas 使用。我希望这里有人可以帮助我。这对我来说当然很复杂,因为我在 JQuery 动画方面没有专业知识。我不知道从哪里开始,我已经坚持了 3 个星期,而且我似乎无法获得适当的参考。提前感谢您的帮助。

您已经花了 3 周的时间完成这项任务...哎哟!

这是一个分步教程,展示了如何管理它。

由于您处于学习模式,我省略了一个演示,以便您可以通过组装来学习。我也把箭头留给你作为学习经验。祝你的项目好运!

计算一些关于 P1 和 P2 之间路径的有用值

创建点 P1 和 P2,您想要沿其设置箭头动画:

var p1={x:0, y:100};
var p2={x:100, y:0};

计算代表当前路径(P1到P2)的起点和终点之间的向量的deltaX和deltaY:

// calculate the deltaX & deltaY of the line between point P1 & P2
var pathStarts={ x:p1.x, y:p1.y };
var pathEnds={ x:p2.x, y:p2.y };
var dx=pathEnds.x-pathStarts.x;
var dy=pathEnds.y-pathStarts.y;

计算P1和P2之间的路径长度:

var pathLength=Math.sqrt(dx*dx+dy*dy);

计算P1和P2之间路径的角度:

var pathAngle=Math.atan2(dy,dx);

定义一个变量,表示箭头线沿 P1 和 P2 之间的路径移动了多远

// pct will be incremented from 0 to 100
// At 100 the arrow-line will have its arrowhead at P2
var pct=0;

定义箭头线的长度:

var arrowLineLength=25;

定义箭头的长度:

var arrowLength=8;

在动画循环中:

您可以使用 requestAnimationFrame

创建动画循环
function animate(time){

    // Recalculate your animation values
    // In your case, recalculate the new starting & ending points 
    //     of the arrow as it animates from P1 to P2

    // Draw your arrow-line in it's newly animated position

    // request another loop in the animation
    requestAnimationFrame(animate);
}

计算箭头线的当前起点和终点

// calculate how far the line has already animated
// shorten the distance by the length used by the arrowLine
var traveled=(pathLength-arrowLineLength)*pct/100;

// calculate the new starting point of the arrow-line
var x0=pathStarts.x+traveled*Math.cos(pathAngle);
var y0=pathStarts.y+traveled*Math.sin(pathAngle);
var lineStart={x:x0,y:y0};

// calculate the new ending point of the arrow-line
var x1=pathStarts.x+(traveled+arrowLineLength)*Math.cos(pathAngle);
var y1=pathStarts.y+(traveled+arrowLineLength)*Math.sin(pathAngle);
var lineEnd={x:x1,y:y1};

清除整个canvas:

ctx.clearRect(0,0,canvas.width,canvas.height);

在新的 [x0,y0],[x1,y1] 位置重新画线:

(参见下面的函数,其中显示了如何绘制箭头线)

drawLineWithArrowhead(lineStart,lineEnd,arrowLength);

增加动画中下一个循环的 pct

pct++;

当您完成 P1 和 P2 之间的动画时(当 pct==100 时)...

返回第一组指令并计算有关 P2 和 P3 之间路径的有用值。

如何在两点之间画一条箭头线:

(有关演示,请参阅之前的回答 here

function drawLineWithArrowhead(p0,p1,headLength){

  // constants (could be declared as globals outside this function)
  var PI=Math.PI;
  var degreesInRadians225=225*PI/180;
  var degreesInRadians135=135*PI/180;

  // calc the angle of the line
  var dx=p1.x-p0.x;
  var dy=p1.y-p0.y;
  var angle=Math.atan2(dy,dx);

  // calc arrowhead points
  var x225=p1.x+headLength*Math.cos(angle+degreesInRadians225);
  var y225=p1.y+headLength*Math.sin(angle+degreesInRadians225);
  var x135=p1.x+headLength*Math.cos(angle+degreesInRadians135);
  var y135=p1.y+headLength*Math.sin(angle+degreesInRadians135);

  // draw line plus arrowhead
  ctx.beginPath();
  // draw the line from p0 to p1
  ctx.moveTo(p0.x,p0.y);
  ctx.lineTo(p1.x,p1.y);
  // draw partial arrowhead at 225 degrees
  ctx.moveTo(p1.x,p1.y);
  ctx.lineTo(x225,y225);
  // draw partial arrowhead at 135 degrees
  ctx.moveTo(p1.x,p1.y);
  ctx.lineTo(x135,y135);
  // stroke the line and arrowhead
  ctx.stroke();
}