Jump to content
Search Community

Accessing the source code of motionPathPlugin

jsco test
Moderator Tag

Recommended Posts

I'm developing an app that needs to animate objects along svg paths but also do advanced stuff like detecting the collision of objects on the same path, pausing/restarting the position of individual elements and so on. I tried doing this with the MotionPathPlugin but it didn't work the way I needed. Is there any way I can get the unminified code of the plugin to extend it to my needs or any other, more precise, way to animate elements along an svg path?

Link to comment
Share on other sites

Hey jsco and welcome.

 

6 minutes ago, jsco said:

Is there any way I can get the unminified code of the plugin to extend it to my needs or any other, more precise, way to animate elements along an svg path?

Sure, you can view the source code on GitHub. However, it may prove more difficult than you imagine to extend it to all of your needs. 

 

4 minutes ago, jsco said:

pausing/restarting the position of individual elements

This is straightforward if you have a tween/timeline for each element. .pause() and .restart() have you covered :) 

 

5 minutes ago, jsco said:

detecting the collision of objects on the same path

Collision detection is not always easy with non-rectangular shapes. But it is completely separate from movement along a path (other than using some data object to keep track of which path the elements are on). 

 

Maybe if you talked about your end goal we could help give you some direction.

  • Like 4
Link to comment
Share on other sites

thanks for the help @ZachSaucier!

 

I'm visualizing an assembly line. Below is a screenshot of how it looks. It need to show rectangles moving along multiple paths, choosing the next path and stopping if there's another element in front of it.


The reasons I struggled with this using just gsap are:

  1. I need to be able to change the speed while the animation is playing (based on its position)
  2. For collision detection (which I would do by just getting the distance traveled of an element on the path, and comparing it to the position of all other elements)
  3. Elements need to play/pause when they detect an element in front of it. I've used paused(true|false) to start/stop the animation but had some issues where onComplete() is called before it's supposed to.  I'll try to get a reproduction ready for that soon.
  4. All of this should be pretty precise

 

 

I based the collision detection on tl.progress()but am a bit concerned about both performance and precision since I have to call it pretty much every ms on all of my elements.


 

 

Screenshot from 2020-03-14 14-18-03.png

Link to comment
Share on other sites

What would likely make the most sense is creating a data representation of the states first and foremost. Then update the visualization based on the data.

 

For example maybe you have something like this:

var beginningState = { pos1: elemReference, pos2: elemReference, pos3: null, /* ... */};
var pathOneState = { pos1: elemReference, pos2: elemReference, pos3: null, /* ... */};
var pathTwoState = { pos1: elemReference, pos2: null, pos3: null, /* ... */};

function updateState() {
  // logic related to updating the state
  
  // for example
  pathOneState.pos3 = beginningState.pos1;
  // loop through the rest of the beginning state (not null) to move them up a position
}

// Call this function after all of your state updates have been completed for that point in time
// in order to minimize the number of visual updates that have to happen
function updateVis() {
  // animate the elements to the visual representation of the state that they are in
}

But maybe a different way of storing would be better for your needs. I dunno, but that's the type of approach that I'd use. The benefits are that you don't have to worry about visual collisions or playing/pausing stuff, you just have to worry about data/state management. It'd be perfectly precise. 

 

Changing the speed of the animation at different parts is pretty easy. You can either use custom eases or tween other tweens/timelines.

 

Hopefully that's helpful!

  • Thanks 1
Link to comment
Share on other sites

20 hours ago, jsco said:

advanced stuff like detecting the collision of objects

 

You may find the examples by @OSUblake in this thread of interest for formulating some logic regarding collision detections.

 

1 hour ago, jsco said:

just use the native getPointAtLength and getTotalLength functions together

 

Users should be aware and keep in mind though that the GreenSock plugins like morphSVG, DrawSVG, motionPathPlugin, etc., were developed to compensate for a wide range of cross browser inconsistances and bugs without the need for additional workarounds.

 

  • Like 4
Link to comment
Share on other sites

1 hour ago, jsco said:

In case anyone else comes across this, animating along a path is actually fairly straightforward, just use the native getPointAtLength and getTotalLength functions together and take the point for every percentage of the path. 

Yes, but some browsers don't report length correctly in certain circumstances, and I'm not entirely sure about the performance implications of doing it the way you suggested. I know that in MotionPathPlugin, I do a bunch of work up front to analyze the path and create a lookup table with measurements so that during the animation it's very fast to plot positions.

 

The other thing is that MotionPathPlugin's align capabilities are unmatched as far as I know - the technique you described only gives you the raw coordinates from the actual SVG path in its own coordinate space, thus it's...um...challenging to, for example, take a <div> and place it exactly on top of that path. Plus MotionPathPlugin can convert other shapes like <circle>, <rect>, etc. into a <path>, or it can use raw points or bezier data to plot things. Heck, it can even animate through arbitrary property values, not just x,y positional data. 

 

That's not to say you shouldn't use the technique you described that circumvents MotionPathPlugin - I'm just recommending that you keep the caveats in mind :)

  • Like 1
Link to comment
Share on other sites

2 hours ago, jsco said:
  • I need to be able to change the speed while the animation is playing (based on its position)

That's super easy - change the timeScale(). You can do that dynamically. You can even tween it. Or like Zach said, tween between positions of a timeline and use whatever duration you want. 

 

2 hours ago, jsco said:

I based the collision detection on tl.progress()but am a bit concerned about both performance and precision since I have to call it pretty much every ms on all of my elements.

I definitely wouldn't do that. I may be misunderstanding your setup, but I'd do the collision detection stuff ahead of time and figure out exactly what progress value ranges map to which elements (like element1 takes up 0.0142 worth of progress on each side of its position) so that it's very easy to figure out where the boundaries are rather than constantly doing expensive operations that check bounds on every tick. And again, do as much work ahead of time as you can so that at runtime it's super cheap and the animation can run smoothly. 

 

Anyway, just some thoughts. I hope that helps. 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...