Amini
Amini

Reputation: 1792

animating(playing) Lottie files with gsap/scrollTrigger

we're trying to animate(play) the Lottie files with gsap/scrollTrigger. The scroll works fine until I reach the part where we should use scrollTrigger to animate some elements.

This is the code that we have for now. You can simply put these code snippets in codepen to use them. Or if you want it to be easier search my name amini-py in codepen.

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js" integrity="sha512-VEBjfxWUOyzl0bAwh4gdLEaQyDYPvLrZql3pw1ifgb6fhEvZl9iDDehwHZ+dsMzA0Jfww8Xt7COSZuJ/slxc4Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/ScrollTrigger.min.js" integrity="sha512-v8B8T8l8JiiJRGomPd2k+bPS98RWBLGChFMJbK1hmHiDHYq0EjdQl20LyWeIs+MGRLTWBycJGEGAjKkEtd7w5Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/@lottiefiles/[email protected]/dist/lottie-interactivity.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@lottiefiles/[email protected]/dist/lottie-player.min.js"></script>
  <div class="wrapper-child">
    <div class="child">
      <h5>First</h5>
      <p>lorem ipsum sit amet sssssssssssssssssssssss</p>
    </div>
    <div class="child">
      <h5>Second</h5>
      <p>lorem ipsum sit amet sssssssssssssssssssssss</p>
    </div>
    <div class="child">
      <h5>Thirds</h5>
      <p>lorem ipsum sit amet sssssssssssssssssssssss</p>
    </div>
    <div class="child">
      <h5>Fourth</h5>
      <p>lorem ipsum sit amet sssssssssssssssssssssss</p>
    </div>
    <div class="child">
      <h5>Fifth</h5>
      <p>lorem ipsum sit amet sssssssssssssssssssssss</p>
    </div>
</section>
  width: 90vw;
  height: 250px;
  overflow-y: hidden;
  display: flex;
}

.wrapper-child {
  border: 1px solid red;
  width: 50%;
}
LottieInteractivity.create({
  player: "#firstLottie",
  mode: "scroll",
  actions: [
    {
      visibility: [0, 1.0],
      type: "seek",
      frames: [0, 300]
    }
  ]
});

gsap.registerPlugin(ScrollTrigger);

const sections = gsap.utils.toArray(".child");

gsap.to(sections, {
  yPercent: -100 * (sections.length - 1),
  ease: "none",
  scrollTrigger: {
    trigger: ".wrapper",
    pin: true,
    scrub: 1,
    start: "top center",
    end: () => "+=" + document.querySelector(".wrapper").offsetHeight
  }
});

Upvotes: 2

Views: 1674

Answers (2)

Flamingo
Flamingo

Reputation: 365

  • is this what you are looking for (add Lottie animation in Gsap timeline scrubbed with scrollTriger )?

import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import lottie from "lottie-web";

// Register the ScrollTrigger plugin with GSAP
gsap.registerPlugin(ScrollTrigger);

// lotties animation

const lottieContainer = document.querySelector(".ai__mockup-lottie");

let playhead = { frame: 0 },
    animation = lottie.loadAnimation({
        container: lottieContainer,
        renderer: "svg",
        loop: false,
        autoplay: false,
        path: lottieContainer.dataset.src, 
    });



// section animation

animation.addEventListener("DOMLoaded", function () {
    let tl = gsap.timeline({
        scrollTrigger: {
            trigger: ".ai__main",
            pin: true, 
            pinReparent: true,
            // anticipatePin: .2, // may help avoid jump
            start: "top top", // when the top of the trigger hits the top of the viewport
            end: "+=2000", // end after scrolling 2000px beyond the start
            scrub: 1, // smooth scrubbing, takes 1 second to "catch up" to the scrollbar
            markers: true,
        },
    });
  
// use lotties animation with scrolltrigger
    tl.to(playhead, {
        frame: animation.totalFrames - 1,
        duration: lottieContainer.dataset.duration,
        ease: "none",
        onUpdate: () => animation.goToAndStop(playhead.frame, true),
    })
  .to(".ai__desc", { rotation: 360 });
});

Upvotes: 0

sungryeol
sungryeol

Reputation: 4015

GSAP is not necessary. I recommend using browser's Intersection Observer API

working demo: https://codepen.io/rabelais88/pen/NWYRXdJ

<script src="...your lottie url"></script>
<style>
body {
  overflow-y: scroll;
}

#root {
  height: 10000px;
}

.lottie-player {
  position: fixed;
  top: 0;
  left: 0;
}

p {
  padding: 20px;
}

.anchor {
  position: absolute;
  top: 5000px;
}

</style>
<div id="root">
  <div style="width: 300px; height: 300px;" class="lottie-player" data-animation-path="https://assets8.lottiefiles.com/packages/lf20_pjulrn8x.json"></div>

  <p>scroll downward to make it work!</p>
  <p class="anchor">animation activates here</p>
</div>
const lottiePlayer = document.querySelector(".lottie-player");

lottie.loadAnimation({
  container: lottiePlayer,
  renderer: "svg",
  loop: true,
  autoplay: false,
  path: lottiePlayer.dataset.animationPath,
  name: "on-scroll-anim"
});

const options = {
  root: null,
  rootMargin: "0px",
  threshold: [0, 0.2, 1]
};

const handleIntersect = (entries) => {
  const anchor = entries[0];
  if (anchor.isIntersecting && anchor.intersectionRatio >= 0.2) {
    lottie.play("on-scroll-anim");
  } else {
    lottie.pause("on-scroll-anim");
  }
};

const observer = new IntersectionObserver(handleIntersect, options);
observer.observe(document.querySelector(".anchor"));

Upvotes: 0

Related Questions