【问题标题】:How to make an arrow move across the canvas?如何在画布上移动箭头?
【发布时间】:2016-10-13 09:25:36
【问题描述】:

我需要按以下顺序对箭头 1-5 进行动画处理(请参见附图)

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

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

【问题讨论】:

  • 您的问题有几个单独的问题,这使其过于宽泛。试着找出一个你卡住或没有按预期工作的特定部分。
  • @4castle 我刚刚指定了问题
  • 感谢您缩小问题范围。为了帮助了解从哪里开始,请尝试在 Google 上搜索如何制作动画。如果不提供任何具体代码,很难说出你到底卡在什么地方。
  • 您似乎已经在your previous question 上获得了一些帮助。有什么东西让你卡住了吗?与其发布重复的问题,不如编辑您之前的问题,以便每个人都可以在一个地方获得所有信息。
  • @4castle 注意到。下次会这样做谢谢。另一个问题是关于旋转箭头,因为它接触到画布的一侧,然后在结果方向上移动。那是使用jCanvas,我设法用五个不同层上的五个箭头来做到这一点。现在我只想使用一个箭头(或任何最好的方法)并将其移动到附图中的方向。我不能使用它的原因是因为我还需要在箭头的尾部创建一个耀斑。

标签: javascript jquery html5-canvas jquery-animate


【解决方案1】:

你已经花了 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};

清除整个画布:

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();
}

【讨论】:

  • 我已经尝试过您提供的分步教程。 jsfiddle.net/4bfxLpz6/1 。我哪里错了?
  • 1.您需要通过调用requestAnimationFrame(animate) 来启动动画运行。 2. 通用变量应该在animate() 循环之外声明,这样当你到达P2 之后,你就可以从P2 进一步到达P3。 3. 您忘记声明一些基本变量。您的小提琴的工作版本是here。干杯!
  • 注明。我将使用相同的概念研究其他箭头。我仍在尝试并将尝试为其他箭头设置动画。希望我不会打扰你。谢谢你对我的耐心。
  • 我总是很乐意帮助任何想要学习新事物的人! :-)
  • 我该在哪里干预才能加快速度?