Copied SVG to clipboard
Something went wrong
Copied code to clipboard
Something went wrong
Saved to bookmarks!
Removed from bookmarks

Default

User image

Default

Name

  • -€50
    Upgrade to Lifetime
The Vault/

Falling Text with Gravity

Falling Text with Gravity

Documentation

Webflow

Code

Setup: External Scripts

External Scripts in Webflow

Make sure to always put the External Scripts before the Javascript step of the resource.

In this video you learn where to put these in your Webflow project? Or how to include a paid GSAP Club plugin in your project?

HTML

Copy
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/Physics2DPlugin.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/SplitText.min.js"></script>

Step 1: Copy structure to Webflow

Copy structure to Webflow

In the video below we described how you can copy + paste the structure of this resource to your Webflow project.

Copy to Webflow

Webflow structure is not required for this resource.

Step 1: Add HTML

HTML

Copy
<div class="drop-wrapper">
  <div class="drop-section">
    <h1 data-drop-text="" class="drop-heading">This is just a<span data-drop-img="" class="drop-heading-img is--first"><img src="https://cdn.prod.website-files.com/681a615bf5a0f1ba3cb1ca38/681a62d0bb34b74d3514ecab_shape-squigle-1.png"></span>random quote<span data-drop-img="" class="drop-heading-img is--second"><img src="https://cdn.prod.website-files.com/681a615bf5a0f1ba3cb1ca38/681a62d0bb34b74d3514ecad_shape-squigle-2.png"></span>we used</h1>
  </div>
  <div class="drop-section">
    <h1 data-drop-text="" class="drop-heading">See how our window acts like<span data-drop-img="" class="drop-heading-img is--third"><img src="https://cdn.prod.website-files.com/681a615bf5a0f1ba3cb1ca38/681a62d0bb34b74d3514ecaf_shape-squigle-3.png"></span> a roof?</h1>
  </div>
  <div class="drop-section">
    <h1 data-drop-text="" class="drop-heading">So much fun!</h1>
  </div>
</div>

HTML structure is not required for this resource.

Step 2: Add CSS

CSS

Copy
.drop-wrapper {
  width: 100%;
  min-height: 350vh;
}

.drop-section {
  justify-content: center;
  align-items: center;
  width: 100%;
  min-height: 100vh;
  display: flex;
  position: relative;
}

.drop-heading {
  text-align: center;
  max-width: 40rem;
  margin-top: 0;
  margin-bottom: 0;
  font-size: 4rem;
  font-weight: 500;
  line-height: 1;
}

.drop-heading-img {
  z-index: 2;
  width: 1.2em;
  display: inline-block;
  position: relative;
}

.drop-heading-img img {
  width: 100%;
  max-width: 100%;
}

.drop-heading-img.is--first {
  transform: rotate(-20deg)translate(.15em, -.2em);
}

.drop-heading-img.is--second {
  transform: translate(-.1em, 0.2em)rotate(10deg);
}

.drop-heading-img.is--third {
  margin-left: -.1em;
  margin-right: -.1em;
  margin-top: -.2em;
  transform: translate(-.05em, .1em)rotate(50deg);
}

[data-drop-text] .line { 
  display: block;
}

Step 2: Add custom Javascript

Custom Javascript in Webflow

In this video, Ilja gives you some guidance about using JavaScript in Webflow:

Step 2: Add Javascript

Step 3: Add Javascript

Javascript

Copy
gsap.registerPlugin(ScrollTrigger, SplitText, Physics2DPlugin);

function initFallingTextGravity() {
  new SplitText("[data-drop-text]", {
    type: "lines, chars",
    autoSplit: true, // resplit split if the element resizes and it's split by lines
    linesClass: "line",
    onSplit(self) {
      // use a context to collect up all the animations
      let ctx = gsap.context(() => {
        self.lines.forEach((line) => { // loop around the lines
          // only one timeline per line rather than one per element
          gsap
            .timeline({
              scrollTrigger: {
                once: true, // only fire once
                trigger: line, // use the line as a trigger
                start: "top top-=10" // adjust offset as you see fit
              }
            })
            .to(line.children, { // target the children
              duration: "random(1.5, 3)", // Use GSAP utils for randomized values
              physics2D: {
                velocity: "random(500, 1000)",
                angle: 90,
                gravity: 3000
              },
              rotation: "random(-90, 90)",
              ease: "none"
            })
            .to(line.children,{ // towards the end of the 'fall', fade out the elements
              autoAlpha: 0,
              duration: 0.2
            }, "-=.2");
        });
      });

      return ctx; // return our animations so GSAP can clean them up when onSplit fires
    }
  });
}

// Initialize Falling Text with Gravity
document.addEventListener("DOMContentLoaded", () => {
  initFallingTextGravity();
});

Step 3: Add custom CSS

Step 2: Add custom CSS

Custom CSS in Webflow

Curious about where to put custom CSS in Webflow? Ilja explains it in the below video:

CSS

Copy
[data-drop-text] .line { display: block;}

Implementation

We’re combining the SplitText + Physics2D plugins from GSAP in this one. On scroll your headings shatter into characters and “fall” off the top of the viewport, as if they hit a ‘roof’.

1. Add the target attribute

Add the data-drop-text attribute to any heading you want to target.

2. Find and split all the targets

In our JS, we create a new SplitText instance for all of our targets. We split the text in lines, and then in separate letters. The lines are used as triggers in our ScrollTrigger (see next step) and the characters of course for our animation. Setting autoSplit to true means our SplitText will revert, and then re-init on resize, if our text wraps. That's why we use the onSplit() callback to create our animation in the next step. A great way to make any SplitText animation responsive easily!

3. ScrollTrigger Setup

In our onSplit callback, we loop over each line in the heading, inside of a context. This context, which we return at the end, makes sure GSAP can clean up this animation whenever the text re-splits.

In our loop, we create a ScrollTrigger for each line, and we set once: true, so our animation only fires once. In step 4 we’ll add our animation!

It’s worth playing around with the start values to really nail the moment where your text visually ‘touches’ the top of the window. For our font, size, and line-height combo, an offset of 10px worked great.

4. Drop the letters with Physics2D

Now, let’s add 2 tweens to our timeline. The first one, using the Physics2D plugin, sends each child element of the line, flying straight down with randomized velocity, angle, and gravity. A second tween makes sure the elements are faded out towards the end.

Definitely have a look around the Physics2D docs to check the values and options you can tweak to really make this exactly like you want it! I'll explain the ones we used:

  • Velocity → The initial velocity of the object measured in pixels per time unit. We used a random value between 500 and 100 to make all letters fall a bit more natural.
  • Angle → The initial angle (in degrees) at which the object should travel. This only matters when a velocity is defined. You could make this a random value between 80 and 100 for example, to make the letters spread out a bit. Just an idea!
  • Gravity → The amount of downward acceleration applied to the object, measured in pixels per second. A higher value will mean the letters fall faster.

Resource Details

GSAP
Physics
Typography
SplitText
Letters
Animation
Falling
Gravity

Original source

Osmo

Creator Credits

We always strive to credit creators as accurately as possible. While similar concepts might appear online, we aim to provide proper and respectful attribution.