angular-gsap

Example · Observer + Inertia + MotionPath

A momentum loop

Wheel, drag, or swipe anywhere on the stage and the chips ride the track; flick and let go, and InertiaPlugin keeps them gliding with your real release velocity. One Observer normalizes every input, and the whole loop is a single number that GSAP tweens.

ObserverInertiaPluginMotionPath
SCROLL SPLIT FLIP MORPH DRAW MOTION OBSERVER INERTIA

wheel · drag · flick · momentum carries it

loop.ts
state = { p: 0 }; // the whole loop is one number

ref = injectGsap(({ gsap }) => {
  // paused motionPath tweens as position setters
  const setters = chips.map((chip, i) => {
    const t = gsap.to(chip, {
      motionPath: { path, align: path,
        alignOrigin: [0.5, 0.5] },
      ease: 'none', paused: true,
    });
    return (p) => t.progress((p + i / n) % 1);
  });
  const render = () =>
    setters.forEach((s) => s(this.state.p));

  const observer = Observer.create({
    target: stage,
    type: 'wheel,touch,pointer',
    onChange: (self) => {
      this.state.p -= self.deltaY * 0.00045;
      render();
    },
    onRelease: (self) =>
      // inertia on a plain number
      gsap.to(this.state, {
        inertia: {
          p: { velocity: -self.velocityY * 0.00045 },
        },
        onUpdate: render,
      }),
  });

  return () => observer.kill();
});

How this works

  • Each chip has a paused motionPath tween used as a position setter: the loop's state is one number p, and every chip renders at p plus its offset. Move the number, the whole train moves.
  • Observer merges wheel, touch, and pointer into one stream. While you drag it adds deltas to p; the moment you release, the gesture velocity is handed to InertiaPlugin.
  • InertiaPlugin doesn't care that p isn't an element: gsap.to(state, { inertia: { p: { velocity } } }) glides any property with physical friction, exactly like the thrown bricks on the Draggable page.
  • Everything is created inside the callback: leave the page and the Observer, the setters, and the ambient drift are all torn down.