Jump to content


Refresh Element Position Dynamically

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

I know the PathEditor is undocumented and unsupported so this isn't a question regarding its use. The reason it is used is because I'm trying to use its onUpdate callback to update the position of the animated element (image in the codepen) as a path node is dragged. For example, if I drag the right-most node to the left (in the codepen), the plane should move to the left as it follows the change in the path's position change. Is there a ready-to-use function in GSAP to make this happen?

See the Pen 55b372c591dcc7e2bdb2afff89d72a18?editors=0010 by swampthang (@swampthang) on CodePen

Link to comment
Share on other sites

Ok, all working now. Thanks again for your help, Jack. Another shoutout to Jack and team for such an awesome library!

  • Like 2
Link to comment
Share on other sites

Hey, Jack, is there an onDrag callback for pathEditor? 

Link to comment
Share on other sites

24 minutes ago, swampthang said:

Hey, Jack, is there an onDrag callback for pathEditor? 


Wouldn't that be the same thing as the onUpdate that's used in the demo above? Is there something else you're looking for? 

Link to comment
Share on other sites

When you drag the entire path the onUpdate doesn’t fire. I guess I could just create a change listener for the path, huh?

Link to comment
Share on other sites

Oh, right - there's not an event that fires when the entire path is dragged. 

Link to comment
Share on other sites

Thanks. For anyone else interested in this sort of thing, I ended up setting up a MutationObserver and it works like a charm. In config I set it to listen only to attributes and on the path there's a transform attribute. MutationObserver allows you to snag the old value so creating a delta was easy-peasy. You have to pass that in as part of the config setup though like...


config = {attributes: true, attributeOldValue: true}


It does return that old value as a string like "matrix(1 0 0 1 23 8)" so you have to get the x/y values out of that. Here's my code in case anyone is interested. I'll refactor it but this gets the job done. I have 2 things that have to be moved with it - a dragger and a wrapper for the image. The element IDs are stored in variables passed as an object to the function but this is the listener setup...


function setPathDragListener(B) {
  // set up mutationObserver
  let path = document.getElementById(B.settings.imageBez.pathID),
      wrapper = document.getElementById(B.settings.imageBez.wrapperID),
      dragger = B.dragger[0].target,
      config = {attributes: true, attributeOldValue: true},
      callback = function(mutationsList, observer) {
        for( let mutation of mutationsList ) {
          let matrix = mutation.target.getCTM();
          if( mutation.oldValue === null ) return;
          let old = mutation.oldValue;
          let n = old.split(' ');
          if( n === null || n[4] === undefined || n[5] === undefined ) return;
          oldX = parseInt(n[4]);
          oldY = parseInt(n[5].replace(')',''));
          let xDiff = matrix.e - oldX;
          let yDiff = matrix.f - oldY;
          let wrapperX = wrapper._gsTransform.x,
              wrapperY = wrapper._gsTransform.y;

          TweenMax.set([dragger,wrapper],{x: (wrapperX + xDiff), y: (wrapperY + yDiff)});
  let observer = new MutationObserver(callback);


  • 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.