0

I need to animate arrow 1-5 in the following order (please see the attached image)

Eg: Arrow 1 will move from point 1 to point 2 then Arrow 2 will move from point 2 to point 3 ... until arrow 5.

Arrow animation reference

Please see: I am required to use only through JQuery and HTML5 canvas. I hope that somebody here can help me with this. It's certainly complex for me as I have no expertise in JQuery animation. I have no idea where to start, I've been stuck on this for 3 weeks and I can't seem to get a proper reference. Appreciate your help in advance.

developer5Urban
  • 43
  • 1
  • 12
  • Your question has several separate questions to it which make it too broad. Try to find a single specific part that you got stuck on or that didn't work as expected. – 4castle Jun 13 '16 at 04:13
  • @4castle I have just specified the question – developer5Urban Jun 13 '16 at 04:32
  • Thanks for narrowing the question. To help with knowing where to start, try making a Google search for how to make an animation. Without providing any specific code, it's hard to tell what exactly you're stuck on. – 4castle Jun 13 '16 at 04:39
  • 1
    It seems you already got some help regarding this on [your previous question](http://stackoverflow.com/questions/37403361/how-to-animate-an-arrow-around-a-canvas). Is there something there that you got stuck on? Rather than posting a duplicate question, it is better to edit your previous question so that everyone can have all of the information in one place. – 4castle Jun 13 '16 at 04:53
  • @4castle noted. Will do that the next time thanks. The other question was about rotating the arrow as it contacts to the side of the canvas and then move in the resultant direction. That was using jCanvas, I manage to do it with five arrows on five different layers. Now I want to use only one arrow (or whichever the best way to do it) and move it onto the direction as in the attached picture. The reason I can't use that is because I need to also create a flare on the tail of the arrow. – developer5Urban Jun 13 '16 at 06:07

1 Answers1

2

You've spent 3 weeks fighting this task...ouch!

Here's a step-by-step tutorial showing how to manage it.

Since you're in learning mode, I leave out a demo so you can learn by assembling the pieces. I also leave the arrow-tail to you as a learning experience. Good luck with your project!

Calculate some useful values about the path between P1 & P2

Create points P1 & P2 that you want to animate an arrow-line along:

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

Calculate the deltaX & deltaY representing the vector between the starting & ending points of the current path (P1 to P2):

// 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;

Calculate the length of the path between P1 & P2:

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

Calculate the angle of the path between P1 & P2:

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

Define a variable that will tell how far along the path between P1 & P2 that the arrow-line has moved

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

Define how long the arrow-line will be:

var arrowLineLength=25;

Define how long the arrowhead will be:

var arrowLength=8;

In an animation loop:

You can create an animation loop using 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 the current starting & ending points of the arrow-line

// 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};

Clear the entire canvas:

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

Redraw the line in it's new [x0,y0],[x1,y1] position:

(See the function below which shows how to draw an arrowLine)

drawLineWithArrowhead(lineStart,lineEnd,arrowLength);

Increase the pct for the next loop in the animation

pct++;

When you finish animating between P1 & P2 (when pct==100)...

Go back to the first set of instructions and calculate useful values about the path between P2 & P3.

How to draw an arrow-line between 2 points:

(See previous answer here for a demo)

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();
}
Community
  • 1
  • 1
markE
  • 102,905
  • 11
  • 164
  • 176
  • I have tried the step by step tutorial you provided. https://jsfiddle.net/4bfxLpz6/1/ . Where am I wrong here? – developer5Urban Jun 14 '16 at 03:35
  • 1. You need to start the animation running by calling `requestAnimationFrame(animate)`. 2. The general variables should be declared outside the `animate()` loop so after you get to P2 then you can go further from P2 to P3. 3. You forgot to declare a few essential variables. A working version of your fiddle is [here](https://jsfiddle.net/m1erickson/x1m81297/). Cheers! – markE Jun 14 '16 at 04:12
  • 1
    Noted. I will work on the other arrows with the same concept. I am still trying and will try to animate the other arrows too. Hopefully I won't bug you. Thank you for being patient with me. – developer5Urban Jun 14 '16 at 04:16
  • 1
    I'm always glad to help anyone who want to learn new things! :-) – markE Jun 14 '16 at 04:25
  • Where do I meddle to give it speed? – developer5Urban Jun 14 '16 at 04:35
  • Meddle with `pct` to change speed. `pct+=2` will animate faster while `pct+=0.50` will animate slower. – markE Jun 14 '16 at 04:44
  • Noted. I'm going to try it now. – developer5Urban Jun 14 '16 at 05:00
  • Could you please help me out for this question http://stackoverflow.com/questions/37935618/add-a-fiery-tail-for-the-existing-ball-in-canvas – developer5Urban Jun 22 '16 at 08:45