Search code examples
sveltegsapscrollmagic

Can Svelte be used with ScrollMagic + GSAP


I'm having troubles with getting Svelte to work alongside ScrollMagic & GSAP. I've tried looking into it all day and still can't find a solution. Does it even work with Svelte and is there any Svelte & ScrollMagic templates out there?

Thanks.


Solution

  • I used these instructions as a reference: https://greensock.com/scrollmagic/

    In your svelte project add scrollmagic, gsap, and scrollmagic-plugin-gsap:

    yarn add -D scrollmagic gsap scrollmagic-plugin-gsap
    

    Inside main.js, configure ScrollMagic to use GSAP:

    import ScrollMagic from 'scrollmagic'
    import gsap from 'gsap'
    import { ScrollMagicPluginGsap } from 'scrollmagic-plugin-gsap'
    
    ScrollMagicPluginGsap(ScrollMagic, gsap)
    

    Then in your Svelte component you can define a controller, timeline and screen:

    <!--- App.svelte -->
    <!-- Copied from example here: https://greensock.com/scrollmagic/ -->
    <script>
      import ScrollMagic from 'scrollmagic'
      import { TimelineMax } from 'gsap'
      import { onMount } from 'svelte'
    
      // define a controller and timeline
      const controller = new ScrollMagic.Controller()
      const tl = new TimelineMax()
    
      // after component mounts, setup scene
      onMount(() => {
        // configure timeline
        tl.staggerFrom(".box", 1.5, {
          scale: 0,
          cycle: {
            y: [-50, 50]
          },
          stagger: {
            from: "center",
            amount: 0.75
          }
        })
    
        // define the scene
        const scene = new ScrollMagic.Scene({
          triggerElement: "#stage",
          duration: "50%",
          triggerHook: 0.35
        })
    
        scene.setTween(tl)
        scene.addTo(controller)
      })
    </script>
    
    
    <div class="spacer">
      <h1>This section is just a spacer</h1>
    </div>
    
    <div id="stage">
      <div class="box box1">1</div>
      <div class="box box2">2</div>
      <div class="box box3">3</div>
      <div class="box box4">4</div>
      <div class="box box5">5</div>
      <div class="box box6">6</div>
    </div>
    
    <div class="spacer">
      <h1>This section is just a spacer</h1>
    </div>
    
    <style>
      :global(body) {
        color: #ccc;
        padding: 0;
        margin: 0;
        font-family: 'Roboto', sans-serif;
      }
    
      h1 {
        color:white;
        margin: 0;
      }
    
      #stage{
        height:100vh;
        width: 100%;
        background: #262626;
        display: flex;
        justify-content: center;
        align-items: center;
    
      }
    
      .spacer{
        width:100%;
        height:100vh;
        background:#5386b2;
        display: flex;
        justify-content: center;
        align-items: center;
      }
    
      .box {
        height: 60px;
        width: 60px;
        align-items: center;
        margin: 4px;
        font-size: 1.2em;
        font-weight: 700;
        color: white;
        border-radius: 4px;
        display: flex;
        justify-content: center;
        flex-wrap: wrap;
    
      }
    
      .box1 {
        background-color: #84c186;
      }
    
      .box2 {
        background-color: #8b6c4c;
      }
    
      .box3 {
        background-color: #39a3ee;
      }
    
      .box4 {
        background-color: #ef9144;
      }
    
      .box5 {
        background-color: #cd58eb;
      }
    
      .box6 {
        background-color: #b84b4b;
      }
    </style>
    

    It also works in Svelte's REPL using CDN imports: https://svelte.dev/repl/af0b5d29ca624171941be9fe9574c4f3?version=3.22.2