Jump to content
Search Community

How to guarantee tween properties are updating on resize?

larsvers test
Moderator Tag

Recommended Posts

Hello, 


I have a question about updating a tween's properties on resize. My problem seems to be that although..

 

  1. I kill the tween on resize 
  2. and rebuild the tween with new properties 

 

..the tween still animates between the initial properties set on page load and not the updated properties set on resize. 

 

The following code pen shows my problem: 

 

 

On the blue, left hand side, I have two canvases on top of each other and draw a background image on canvas 1 (black circle with black border). I then need to morph only the circle into a new shape - a rectangle. To achieve this, I draw just a red circle on canvas 2 over the black circle and morph it into the rectangle. This is easily done with MorphSVG's render function. The morphing is triggered with ScrollTrigger (heavy gsap usage here...) when the user scrolls past section 1 on the right hand side. 

 

To always center the image as well as the circle and the rectangle, I calculate a transform on page load and on each resize that I can then apply to the canvas' context so that the circles will always be horizontally centered:

 

transformImg = getTransform(circleImg); 

// will produce somthing like { x: 0, y: -100, scale: 2 } based on the image/path size and the container size.

 

In fact, the red circle and the black circle are from the same base image, so they will always require the same transform.

 

Next, I build out a timeline with two tweens running at the same time:

 

1. a MorphSVG tween that triggers the render function to draw the circle-to-rectangle path:

 

const morph = gsap.to('.circle-path', {
  morphSVG: {
    shape: '.rect-path',
    render: drawMorphPath,
    updateTarget: false,
  },
});

 

2. a tween just updating a global transform object (transformShape) that the morph render function drawMorphPath from tween 1 above uses while morphing. Based on this updating transform the context position updates from the central circle transform to the rectangle transform:

 

const retransform = gsap.fromTo(
  transformShape,
  {
    x: transformCircle.x,
    y: transformCircle.y,
    scale: transformCircle.scale,
  },
  {
    x: transformRectangle.x,
    y: transformRectangle.y,
    scale: transformRectangle.scale,
    onUpdate: updateTransformShape // updating the global transform like so: transformShape = this.targets()[0];
  }
);

 

This works as expected on page load. On resize,

 

  1. it recalculates all transforms,
  2. kills the tweens' timeline (function buildMorphAnim)
  3. and is supposed to build new tweens with the updated transforms.

 

However, rather than updating the from and to vars, the tween seems to recycle the transforms set initially - on page reload. 

 

To see this, you can load and try the pen without resizing. The red circle comes from and returns back to the black circle's position if you scrub-scroll. Then resize a little and retry. The red circle should be out of whack as it is not moving between the desired updated transforms, but the two original transforms supplied on page load.

 

In addition you can open the console and see the desired transforms - logged just before the tween is created - as well as the actual transforms used by the tween logged at tween start and complete, which are not updated after resize.

 

Would you have any idea what I am doing wrong or can amend to make this work? 

 

I apologise for a long question and a more complex test example - as there are quite a few parts possibly responsible for the result, I thought I keep it in. But please let me know if this is all too complex and I will try to tackle it from a simpler angle.

 

Many thanks for any help!
 

 

See the Pen dyGjZYv by doldinger (@doldinger) on CodePen

Link to comment
Share on other sites

Many thanks Zach and I know - I'm really sorry for the question extent! I have indeed seen the post but I believe I can exclude ScrollTrigger as an issue source as it persists when using a click event for example. I kept ScrollTrigger in the pen to allow for easy scrubbing...

 

I'd be super grateful for any pointers you might have after maybe briefly looking at it. But don't worry if this is out of bounds - I shall certainly have a go at de-cluttering then!

Link to comment
Share on other sites

How about this: What's your goal? Maybe we can help give you a method of doing what you need to then you can apply it to your situation.

 

At the moment your demo doesn't have any animation playing even before resize so it's quite hard for me to tell what you're attempting to do.

  • Like 1
Link to comment
Share on other sites

Hi @ZachSaucier, the demo plays the animation when scrolling down (and the issue occurs on loading - resizing - scrolling), but I should've made that clearer. Anyhow - thanks for keeping me honest in terms of post length and example complexity! I felt I couldn't break it down much further, but it probably would've done me good : )

 

I have solved the issue in the meantime. It was a logical error on my side. If anyone followed along (don't if you haven't so far), the problem was that on resize I created a new timeline but re-used the old ScrollTrigger instance which linked to the old timeline and hence drew the object of interest with old values.  Killing the old and creating a new ScrollTrigger instance solved the issue.  Solved here: 

 

See the Pen qBbMgLW by doldinger (@doldinger) on CodePen

 

Again, many thanks for your thoughts!

 

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