| name | fancoolo-fx |
| description | Fancoolo FX — a class-driven GSAP animation wrapper for WordPress and static sites. Use when the user asks about FX animations, fx-text-reveal, fx-reveal, fx-spin-reveal, fx-bg-reveal, fx-scale-in classes, FX.config, tagMap, sectionSelector, modifier classes like fx-duration-[n], or building animations with the fancoolo-fx package. Also use when adding scroll-triggered or page-load animations via CSS classes in WordPress/Gutenberg. |
| license | MIT |
Fancoolo FX
When to Use This Skill
Apply when working with the fancoolo-fx package or when the user mentions:
- FX animation classes (
fx-text-reveal, fx-reveal, fx-spin-reveal, fx-bg-reveal, fx-scale-in, fx-type-writer, fx-draw-svg, fx-parallax, fx-split-words, fx-slide-left, fx-slide-right)
- Trigger suffixes (
-pl, -st, bare classes in sections)
- FX modifier classes (
fx-duration-[n], fx-delay-[n], fx-stagger-[n], fx-ease-[name], fx-start-[pos])
FX.config, __FX_CONFIG__, tagMap, sectionSelector, scrollStart, scrollOnce
- Class-based GSAP animations for WordPress/Gutenberg
Related skills: For GSAP core use gsap-core; for ScrollTrigger use gsap-scrolltrigger; for timelines use gsap-timeline; for GSAP plugins (SplitText etc.) use gsap-plugins; for WordPress blocks use wp-block-development.
What Fancoolo FX Is
A class-driven GSAP animation wrapper. Users add CSS classes to HTML elements and get animations — no JS needed per page. Designed for WordPress/Gutenberg where only class names (not data attributes or inline styles) can be added to blocks.
No build step. GSAP + plugins load as separate script tags, then src/fx.js runs as a plain IIFE.
Installation
npm install
Load in this order:
<script src="node_modules/gsap/dist/gsap.min.js"></script>
<script src="node_modules/gsap/dist/ScrollTrigger.min.js"></script>
<script src="node_modules/gsap/dist/SplitText.min.js"></script>
<script src="src/fx.js"></script>
Effects
| Effect | Class prefix | JS function | What it does | Duration | Ease |
|---|
| Text Reveal | fx-text-reveal | FX.textReveal() | SplitText lines, overflow-hidden mask, slide up | 1.2s | power3.out |
| Reveal | fx-reveal | FX.reveal() | Slide up from y:80 + fade | 1s | power3.out |
| Spin Reveal | fx-spin-reveal | FX.spinReveal() | Rotation:-30 + scale:0.9 + fade | 1.4s | power3.out |
| BG Reveal | fx-bg-reveal | FX.bgReveal() | Slide up from y:100% + fade | 1s | power3.out |
| Scale In | fx-scale-in | FX.scaleIn() | Scale from 0.92 + fade | 1s | power3.out |
| Fade In | fx-fade-in | FX.fadeIn() | Opacity only, no movement | 0.8s | power2.out |
| Blur In | fx-blur-in | FX.blurIn() | Fade in + deblur (camera focus effect) | 1.2s | power2.out |
| Clip Up | fx-clip-up | FX.clipUp() | Clip-path wipe from bottom | 1s | power3.inOut |
| Clip Down | fx-clip-down | FX.clipDown() | Clip-path wipe from top | 1s | power3.inOut |
| Tilt In | fx-tilt-in | FX.tiltIn() | 3D perspective reveal (scrub-based) | 1.4s | power3.out |
| Type Writer | fx-type-writer | FX.typeWriter() | Character-by-character typing reveal | 0.05s | none |
| Draw SVG | fx-draw-svg | FX.drawSVG() | SVG stroke drawing animation | 2s | power2.inOut |
| Parallax | fx-parallax | FX.parallax() | Scrub-based Y-shift on scroll | — | none |
| Split Words | fx-split-words | FX.splitWords() | Word-by-word fade + slide up | 0.8s | power3.out |
| Slide In | fx-slide-left / fx-slide-right | FX.slideIn() | Horizontal slide from left/right | 1s | power3.out |
Stagger Children Modifier
fx-stagger-all-[selector] targets child elements by CSS selector. Must be paired with an effect class.
<div class="fx-stagger-all-[img] fx-reveal-st">
<div class="fx-stagger-all-[h2,p] fx-text-reveal-st">
<div class="fx-stagger-all-[.card] fx-blur-in-st">
Without an effect class, fx-stagger-all does nothing.
Three Trigger Modes
1. Explicit suffix
-pl (page load): <h1 class="fx-text-reveal-pl"> — animates immediately on DOMContentLoaded
-st (scroll trigger): <h2 class="fx-text-reveal-st"> — animates when element scrolls into viewport
2. Bare class in section
<section><h2 class="fx-text-reveal"> — no suffix needed inside a <section>. Auto scroll-triggered using the section as trigger.
3. Tag map (zero classes)
<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>
Elements inside sections animate automatically by tag — no classes needed.
Modifier Classes (Gutenberg-friendly)
Override timing per-element using bracket syntax:
| Modifier | Default | Example |
|---|
fx-duration-[n] | 1.2 (text) / 1 (others) | fx-duration-[2] |
fx-delay-[n] | 0 | fx-delay-[0.3] |
fx-stagger-[n] | 0.1 | fx-stagger-[0.25] |
fx-ease-[name] | power3.out | fx-ease-[power2.inOut] |
fx-start-[pos] | top 85% | fx-start-[top center] |
Example: <h2 class="fx-text-reveal-st fx-duration-[2] fx-stagger-[0.25]">
Config (FX.config)
| Option | Default | Description |
|---|
sectionSelector | 'section' | CSS selector for containers that enable bare-class and tagMap triggering |
scrollStart | 'top 85%' | Default ScrollTrigger start position |
scrollOnce | true | Play once or replay on re-scroll |
tagMap | null | Map of CSS selectors to effect names |
excludeSelectors | '' | CSS selectors for elements to never animate |
disableMobile | false | Skip all animations on mobile |
mobileBreakpoint | 768 | Width threshold for mobile detection (px) |
speedMultiplier | 1 | Global duration multiplier (0.5 = faster, 2 = slower) |
respectReducedMotion | true | Skip animations when OS prefers reduced motion |
Pre-configure via window.__FX_CONFIG__ before the script loads, or modify FX.config at runtime and call FX.init().
JavaScript API
All functions accept (element, options):
FX.textReveal(el, { trigger: 'scroll', delay: 0.2, scrollTrigger: { trigger: parentEl } });
FX.reveal(el, { y: 120 });
FX.spinReveal(el, { rotation: -45, scale: 0.8 });
FX.scaleIn(el, { trigger: 'scroll', scale: 0.85 });
FX.bgReveal(el);
FX.init();
FX.refresh();
FX.typeWriter(el, { trigger: 'scroll' });
FX.drawSVG(svgEl, { trigger: 'scroll' });
FX.parallax(el, { y: 80 });
FX.splitWords(el, { trigger: 'scroll' });
FX.slideIn(el, { direction: 'left', trigger: 'scroll' });
Set trigger: 'scroll' to enable ScrollTrigger. Pass scrollTrigger: { trigger: someEl } to use a different trigger element.
Resize Handling
Text-based effects (textReveal, typeWriter, splitWords) automatically re-split when the browser width changes. One-shot animations revert SplitText on completion so text reflows naturally. Pending scroll-triggered animations are reverted and re-created with correct line breaks. Call FX.refresh() manually after layout changes that don't involve a resize (sidebar toggle, font load).
Auto-stagger
Siblings with the same .fx-* class under the same parent are staggered automatically (0.15s gap between each).
Processing Priority
init() uses a processed Set to avoid double-animating:
-pl classes (page load) — first
-st classes (scroll trigger) — second
- Bare classes in sections — third
- Scrub-based effects (tiltIn, parallax)
- tagMap — last
fx-stagger-all-[selector] modifier
Each step skips already-processed elements.
WordPress / Gutenberg
- Uses CSS classes only — add via "Additional CSS class(es)" in the block sidebar
- No data attributes or inline styles (Gutenberg doesn't support them)
- Bracket syntax for modifiers works in the class field
- Enqueue via
wp_enqueue_script with proper dependencies
wp_enqueue_script('gsap', get_template_directory_uri() . '/assets/js/gsap.min.js', array(), '3.14.2', true);
wp_enqueue_script('gsap-scrolltrigger', get_template_directory_uri() . '/assets/js/ScrollTrigger.min.js', array('gsap'), '3.14.2', true);
wp_enqueue_script('gsap-splittext', get_template_directory_uri() . '/assets/js/SplitText.min.js', array('gsap'), '3.14.2', true);
wp_enqueue_script('fx', get_template_directory_uri() . '/assets/js/fx.js', array('gsap', 'gsap-scrolltrigger', 'gsap-splittext'), '1.0.0', true);
WordPress Plugin Settings
Admin page at Appearance → Fancoolo FX with three tabs:
- Editor — CodeMirror JS editor + settings sidebar
- Config Reference — config options, JS API functions, code examples
- Classes Reference — all available CSS classes
Settings sidebar controls: Scroll Start, Section Selector, Exclude Selectors, Play once, Debug markers, Disable on mobile (with breakpoint), Respect reduced motion, Speed Multiplier, Global Tag Map (repeater), Import/Export/Reset.
All sidebar settings are injected as window.__FX_CONFIG__ before fx.js loads.
Adding New Effects
- Add default config to
EFFECT_DEFAULTS in src/fx.js
- Create the effect function (pattern: resolveOptions, build tweenVars, conditional scrollTrigger, gsap.from)
- Add to
effects map for class-based auto-discovery
- Add to
effectsByName for tagMap lookups
- Add to
window.FX
FOUC Prevention
All effects use autoAlpha instead of opacity — GSAP's autoAlpha combines opacity and visibility, so elements with CSS visibility: hidden are revealed automatically when their animation starts. The WordPress plugin injects visibility: hidden CSS in the <head> for all .fx-* classes. Non-WP users must add this CSS manually (see installation docs).
For text-based effects (textReveal, typeWriter, splitWords), the parent element's visibility is set to inherit before animating children, so the split targets start hidden via autoAlpha: 0 while the container becomes visible.
Key Architecture Decisions
- No build step: plain script tags — simpler for WordPress
wp_enqueue_script
- CSS classes over data attributes: Gutenberg only exposes "Additional CSS classes" field
- Bracket syntax (
fx-duration-[2]): decimal values work in class names, inspired by Tailwind
- GSAP from npm: version-locked via package.json, served from node_modules
window.FX global: project-specific JS can call effects without imports