<!--------- Osmo [https://osmo.supply/] --------->
<section class="section-resource">
<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 loading="lazy" src="https://cdn.prod.website-files.com/681a615bf5a0f1ba3cb1ca38/681a62d0bb34b74d3514ecab_shape-squigle-1.png" alt=""></span>random quote<span data-drop-img="" class="drop-heading-img is--second"><img loading="lazy" src="https://cdn.prod.website-files.com/681a615bf5a0f1ba3cb1ca38/681a62d0bb34b74d3514ecad_shape-squigle-2.png" alt=""></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 loading="lazy" src="https://cdn.prod.website-files.com/681a615bf5a0f1ba3cb1ca38/681a62d0bb34b74d3514ecaf_shape-squigle-3.png" alt=""></span> a roof?</h1>
</div>
<div class="drop-section">
<h1 data-drop-text="" class="drop-heading">So much fun!</h1>
</div>
</div>
</section>
<div class="osmo-credits">
<p class="osmo-credits__p">Resource by <a target="_blank" href="https://www.osmo.supply?utm_source=codepen&utm_medium=pen&utm_campaign=falling-text-with-gravity" class="osmo-credits__p-a">Osmo</a>
</p>
</div>
<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>
/* ------- Osmo [https://osmo.supply/] ------- */
/* Osmo UI: https://slater.app/10324/23333.css */
body {
background-color: #340824;
color: var(--color-light);
font-size: 1vw;
margin: 0;
padding: 0;
overscroll-behavior: none;
min-height: 100%;
font-family: PP Neue Montreal, Arial, sans-serif;
cursor: url("https://cdn.prod.website-files.com/6708f85ff3d3cba6aff436fb/671251b239d7aeb290a31ac5_cursor-default%402x.svg")
2 0,
auto;
}
a,
button {
cursor: url("https://cdn.prod.website-files.com/6708f85ff3d3cba6aff436fb/671251b212e6b71494aa67ff_cursor-pointer%402x.svg")
12 0,
pointer;
}
.section-resource {
justify-content: center;
align-items: center;
min-height: 100vh;
display: flex;
overflow: clip;
}
.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;
}
.osmo-credits {
z-index: 999;
pointer-events: none;
flex-flow: column;
justify-content: center;
align-items: center;
width: 100%;
height: 4em;
padding: 1em;
display: flex;
position: fixed;
bottom: 0;
left: 0;
}
.osmo-credits__p {
pointer-events: auto;
color: #efeeec80;
text-align: center;
margin: 0;
font-family: PP Neue Montreal, Arial, sans-serif;
font-size: 1.125em;
font-weight: 500;
line-height: 1.3;
}
.osmo-credits__p-a {
color: #efeeec;
}
@font-face {
font-family: 'PP Neue Montreal';
src: url('https://cdn.prod.website-files.com/6819ed8312518f61b84824df/6819ed8312518f61b84825ba_PPNeueMontreal-Medium.woff2') format('woff2');
font-weight: 500;
font-style: normal;
font-display: swap;
}
// ------- Osmo [https://osmo.supply/] ------- //
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,
{
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();
});
This Pen doesn't use any external JavaScript resources.