A GSAP animation wrapper for WordPress and static sites. No build step. No JavaScript per page. Just CSS classes.
npm install gsap fancoolo-fx
npmjs.com →
Every element in the hero uses a -pl class to animate on page load. That's it — no JavaScript.
<!-- Background slides up on page load --> <div class="hero-bg fx-bg-reveal-pl"></div> <!-- Badge spins in --> <div class="hero-label fx-spin-reveal-pl">Animation SDK</div> <!-- Heading reveals line by line --> <h1 class="fx-text-reveal-pl">Add a class.<br>Get an animation.</h1> <!-- Paragraph reveals line by line --> <p class="fx-text-reveal-pl">A lightweight GSAP framework...</p> <!-- Tags spin in, auto-staggered because they share a parent --> <div class="hero-badges"> <div class="tag fx-spin-reveal-pl">Page Load</div> <div class="tag fx-spin-reveal-pl">Scroll Trigger</div> <div class="tag fx-spin-reveal-pl">Auto Stagger</div> </div>
Four script tags. That's the entire setup.
<!-- 1. GSAP core --> <script src="node_modules/gsap/dist/gsap.min.js"></script> <!-- 2. Plugins --> <script src="node_modules/gsap/dist/ScrollTrigger.min.js"></script> <script src="node_modules/gsap/dist/SplitText.min.js"></script> <!-- 3. FX SDK --> <script src="src/fx.js"></script>
Splits text into lines, wraps each in an overflow-hidden mask, and animates them in sequence. Works on any text element.
Every line slides up from behind a mask, creating a polished reveal effect that draws the reader's eye.
<!-- Page load --> <h1 class="fx-text-reveal-pl">Hello World</h1> <!-- Scroll triggered --> <h2 class="fx-text-reveal-st">Animates on scroll</h2> <!-- Inside a section (auto scroll-triggered) --> <section> <h2 class="fx-text-reveal">No suffix needed</h2> </section>
Siblings with the same class get auto-staggered with a 0.15s delay between each.
<!-- Auto-staggered siblings --> <div class="grid"> <img src="photo-1.jpg" class="fx-reveal-st" /> <img src="photo-2.jpg" class="fx-reveal-st" /> <img src="photo-3.jpg" class="fx-reveal-st" /> </div> <!-- Single element --> <img src="hero.jpg" class="fx-reveal-pl" />
Rotates from -30deg and scales from 0.9. Great for badges, icons, and decorative elements.
<div class="badge fx-spin-reveal-st">Design</div> <div class="badge fx-spin-reveal-st">Motion</div> <div class="badge fx-spin-reveal-st">Code</div> <!-- On page load --> <div class="icon fx-spin-reveal-pl">...</div>
Scales from 0.92 with a fade. Ideal for cards, hero panels, and featured content.
Drop fx.js into your project and start adding classes.
<div class="card fx-scale-in-st"> <h3>Ready to try it?</h3> <p>Drop fx.js into your project.</p> </div> <!-- Background panel --> <div class="hero-bg fx-bg-reveal-pl"></div>
No inline styles needed. Uses bracket syntax — perfect for Gutenberg's "Additional CSS classes" field.
Animation duration in seconds. Default: 1.2 (text) / 1 (others)
Start delay in seconds. Default: 0
Delay between staggered siblings. Default: 0.1
GSAP easing function. Default: power3.out
And this paragraph has a delayed start.
<!-- Slower text with wider stagger --> <h2 class="fx-text-reveal-st fx-duration-[2] fx-stagger-[0.25]"> Slower and more dramatic </h2> <!-- Delayed start + custom easing --> <p class="fx-reveal-st fx-delay-[0.5] fx-ease-[power2.inOut]"> Custom timing </p>
Elements with bare .fx-text-reveal (no suffix) inside a <section> are auto scroll-triggered.
<!-- No -pl or -st suffix needed inside <section> --> <section> <h2 class="fx-text-reveal">Auto triggered</h2> <p class="fx-text-reveal">By the section</p> <img class="fx-reveal" src="photo.jpg" /> </section>
Configure once — every heading, paragraph, and image inside sections animates automatically by tag name.
Neither does this paragraph. The tagMap config handles it automatically based on the tag name.
<!-- Add this script tag before fx.js --> <script> window.__FX_CONFIG__ = { tagMap: { 'h1,h2,h3,h4,h5,h6': 'textReveal', 'p,blockquote': 'textReveal', 'img,video': 'reveal', } }; </script> <script src="src/fx.js"></script> <!-- Now every section auto-animates by tag --> <section> <h2>No classes needed</h2> <p>This animates automatically</p> <img src="photo.jpg" /> </section>
When classes alone aren't enough, use the FX global for custom orchestration.
// Compound sequence — card scales in, then heading reveals var hero = document.querySelector('.hero'); FX.scaleIn(hero.querySelector('.card'), { trigger: 'scroll', scrollTrigger: { trigger: hero } }); FX.textReveal(hero.querySelector('h2'), { trigger: 'scroll', delay: 0.2, scrollTrigger: { trigger: hero } }); // Available: FX.textReveal, FX.reveal, FX.spinReveal, // FX.bgReveal, FX.scaleIn, FX.init
The most subtle reveal. Elements simply appear without sliding, scaling, or rotating.
<!-- Just fades in, nothing else --> <img src="photo.jpg" class="fx-fade-in-st" /> <!-- Overlay on page load --> <div class="overlay fx-fade-in-pl"></div>
Fades in while deblurring. Organic and cinematic without being dramatic.
This text sharpens as it appears — like adjusting a lens.
<!-- Deblur on scroll --> <h1 class="fx-blur-in-st">Focus reveals beauty</h1> <!-- Hero image on page load --> <img src="hero.jpg" class="fx-blur-in-pl" />
Reveals with a clip-path — no movement, no opacity. Premium architectural feel.
<!-- Wipe from bottom up --> <img src="photo.jpg" class="fx-clip-up-st" /> <!-- Wipe from top down --> <img src="photo.jpg" class="fx-clip-down-st" />
Add the trigger + effect to the container. Children animate automatically.
<!-- Trigger (what) + Effect (how) on the container --> <div class="grid fx-stagger-all-[img] fx-reveal-st"> <img src="1.jpg" /> <img src="2.jpg" /> <img src="3.jpg" /> </div> <!-- Text + blur effect --> <div class="fx-stagger-all-[h2,p] fx-blur-in-st"> <h2>Title</h2> <p>Description</p> </div>
Elements start tilted and scaled, then ease into their natural position as you scroll.
<!-- 3D tilt on scroll --> <img src="photo.jpg" class="fx-tilt-in-st" /> <!-- Card with tilt on page load --> <div class="card fx-tilt-in-pl"> Content </div>