Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to dispose the animation after no longer needed? #196

Open
MurhafSousli opened this issue Jan 7, 2024 · 3 comments
Open

How to dispose the animation after no longer needed? #196

MurhafSousli opened this issue Jan 7, 2024 · 3 comments

Comments

@MurhafSousli
Copy link

I have an option where I need to re-create the animation instance, how can I dispose the animation before creating a new one?

constructor() {
  if (!CSS.supports('animation-timeline', 'scroll()')) {

    if (this.cmp.direction() === 'rtl') {
      this.animation = startPolyfill(this.nativeElement, this.cmp.viewport.nativeElement, this.polyfillAxis, this.polyfillKeyframe);
    } else {
      this.animation = startPolyfill(this.nativeElement, this.cmp.viewport.nativeElement, this.polyfillAxis, this.polyfillKeyframe);
    }
  }
}

function startPolyfill(element: HTMLElement, source: HTMLElement, axis: 'x' | 'y', keyframeProperty: string): Animation {
  return element.animate(
    {
      [keyframeProperty]: [
        'var(--_scrollbar-thumb-transform-from)',
        'var(--_scrollbar-thumb-transform-to)'
      ]
    },
    {
      fill: 'both',
      easing: 'linear',
      timeline: new ScrollTimeline({ source, axis })
    } as any
  );
}
@kevers-google
Copy link
Collaborator

The animation API has a cancel method. In your example, the "if" and "else" blocks look the same. Should the blocks be setting different keyframe options? If so, then rather than cancelling and restarting the animation, calling animation.effect.setKeyframes() is an option.

@MurhafSousli
Copy link
Author

MurhafSousli commented Jan 8, 2024

@kevers-google The parameters are the same, however, the only change is in the CSS variable --_scrollbar-thumb-transform-from and --_scrollbar-thumb-transform-to which is done in CSS. When direction is LTR, I use translate3d but in RTL I have to use right because translate3d in RTL mode goes to the opposite direction in a weird way, even if I invert the position to fix the animation direction, the actual DOM element still goes in the opposite direction making the hover and click events decoupled from the animated element location.

All I need is to re-initialize the animation when the direction is changed.

So the cancel function clean up the animation right?

@kevers-google
Copy link
Collaborator

Yes, animation.cancel() puts the animation into an idle state where it is no longer active. The animation will eventually be garbage collected provided there are no live references in JavaScript.

Canceling and then recreating the animation will work, but could result in flicker in some cases since the animation is momentarily not in effect. You can start the new animation before cancelling the old one to avoid flicker since composite ordering will ensure that the new animation replaces the old one. The reason for cancelling the old animation in this case, is performance and memory (avoid stale animations piling up).

An alternate approach is

requestAnimationFrame(() => {
// Apply CSS change
requestAnamationFrame(() => {
animation.effect.setKeyframes(...);
});
});

In other words, you can replace the keyframes on the existing animation rather than creating a new animation.

Long story short, you have options. If cancelling and creating a new animation works well enough for your application, then that might be simplest. If you encounter flicker problems when restarting the animation, then you can consider one of the other options.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants