3

I'm using paper.js and i'm trying to animate an item along a path I created...

//Path : path = new Path(); path.add(new Point(0,100), new Point(120,100), new Point(120,150)); //Item circle = new Path.Circle(0,100,4); circle.strokeColor = "#EEE"; 

And while animating (with onFrame()) I want the circle to follow the path... Does anyone know how to do that? I didn't found it in the doc or on google.... I hope it's clear enough..

Thanks for the answers!

4 Answers 4

5

Didn't test it yet, but it should be something like this.

// vars var point1 = [0, 100]; var point2 = [120, 100]; var point3 = [120, 150]; // draw the line var path = new Path(); path.add(new Point(point1), new Point(point2), new Point(point3)); path.closed = true; // draw the circle var circle = new Path.Circle(0,100,4); circle.strokeColor = "#EEE"; // target to move to var target = point2; // how many frame does it take to reach a target var steps = 200; // defined vars for onFrame var dX = 0; var dY = 0; // position circle on path circle.position.x = target[0]; circle.position.y = target[1]; function onFrame(event) { //check if cricle reached its target if (Math.round(circle.position.x) == target[0] && Math.round(circle.position.y) == target[1]) { switch(target) { case point1: target = point2; break; case point2: target = point3; break; case point3: target = point1; break; } // calculate the dX and dY dX = (target[0] - circle.position.x)/steps; dY = (target[1] - circle.position.y)/steps; } // do the movement circle.position.x += dX; circle.position.y += dY; } 

Working DEMO

Sign up to request clarification or add additional context in comments.

2 Comments

It works great (you even add an easing effect while being close to the target point) but i had to correct some little things, like circle.position.x instead of circle.x or target[0] / target.x. To remove the easing effects, you have to decrement steps at the end of the frame and reinitialize it in the switch/case. (you can even make a ratio between steps and the current segment length in order to get the same speed on every segments...) Thanks a lot !
I see why the easing effect is there (didn't fully thought it trough), if you set dX and dY within the if statement it should no longer ease out. I will update the code.
4

Solution to more control the speed :

  • the move are proportional to time
  • can set the speed by pixel/second

http://jsbin.com/cukine/28/edit?html,output

var offset = 0; circle.onFrame = function (event) { if (offset< path.length){ circle.position =path.getPointAt(offset); offset+=event.delta*150; // speed - 150px/second } else { offset=0; } } 

3 Comments

Would you care to add an explaination to your answer as to why it is different from the other older posts?
This answer is better than the accepted answer because it relies on Path.getPointAt(offset), rather than re-inventing the wheel.
@secretformula yes read the post : "the move are proportional to time" and "can set the speed by pixel/second"
2

Heres simple solution, i added a method to Point called getPointAtPercent so now you can just run that on your path to get where the point should be.

paper.Path.prototype.getPointAtPercent = function (percent) { return this.getLocationAt(percent * this.length).getPoint(); }; 

Heres an example of it working

http://jsfiddle.net/icodeforlove/uqhr8txp/1/

Comments

0

You have to use the:

path.getLocationAt(); 

method. This method accepts one parameter between 0 and 1, where 0 respresents the start and 1 the end of the path and returns a location.

You can use the:

path.length 

property to calculate the different offsets of the parameter

steps = lengthOfSegmentToWalk / path.length t = 0; while( t <= 1 ){ location = path.getLocationAt( t ); t += step; } 

good luck

edit::

or you can use the

path.flatten( maxDistance ); 

method and read all the points from the resulting path...

4 Comments

Thanks ! I'll try this. But i've done another method which work too. I'm using path.getPointAt(). By calculating a percentage off my animation duration (fixed to 10s), I can get the next point of the path and so animate the item along it. Thanks !
there are many ways, depends on your script, but on thing is for sure: you always have to deal with the parameter from 0 to 1, so if you want to animate over a chain of paths you need to combine them to get their total length.
You should use this instead of my predefined vars.
path.getLocationAt( t ) didn't work for me, it only took me to the next segment. path.getPointAt() on the other hand worked flawlessly!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.