GSAP

Rasuke uses the GSAP npm package (3.15) for almost all motion. There is no AOS, Wow.js, or Swiper animation layer. Official docs: gsap.com

What is registered

src/assets/js/main.js imports GSAP and registers ScrollTrigger, ScrollSmoother, and ScrollToPlugin, then creates a page-level ScrollSmoother on #smooth-wrapper / #smooth-content:

gsap.registerPlugin(ScrollTrigger, ScrollSmoother, ScrollToPlugin);
window.gsap = gsap; window.THREE = THREE; // for classic / debugging consumers

ScrollSmoother.create({
  wrapper: '#smooth-wrapper', content: '#smooth-content',
  smooth: 1.35, smoothTouch: 1.35, // one lag value for every input
  effects: true, ignoreMobileResize: true,
});
  • ScrollTrigger — pins, scrubs, and viewport reveals everywhere.
  • ScrollSmoother — inertia scrolling for the whole page. Skipped when prefers-reduced-motion: reduce is set or the host sets window.rasukeCore.smoothScroll = false; the shell then falls back to native scroll without clipping.
  • ScrollToPlugin — back-to-top and anchor scrolling through the smoother.
  • SplitText — registered by the text modules (text-mark-top, text-mark-left, text-blur-stagger, text-flip, hero-2-title-rotate) for line/char splitting.
How effects attach

Each effect is a small ES module imported by main.js. Modules query a section class or a data-* hook and no-op when the markup is missing, so unused pages stay cheap. Entrance modules that must wait for the preloader (text-mark-*, projects-1, stagger-reveal, hero intros) are gated on the preloader's reveal / done promise; everything else boots immediately. The full catalog is on Effects & Interactions; highlights:

  • preloader.js → preloader/Preloader.js — wordmark + counter + wipe reveal
  • transition.js — page collapse / grow transition between navigations
  • cursor.js — custom comet cursor with labelled discs
  • text-mark-top.js / text-mark-left.js / text-blur-stagger.js / text-flip.js — headline & link reveals
  • grid-wipe.js, stagger-reveal.js, anim-zoomin.js — generic reveal system (data-stagger, .anim-zoomin)
  • scroll-parallax.js, img-1-parallax.js, about-2-parallax.js, scroll-move-up.js — scrubbed parallax
  • marquee.js, digit-count.js — tickers and number rolls
  • showcase-1.js … showcase-6.js, projects-1.js, services-*.js, faqs-*.js — per-section interactions
Authoring rules
  • Keep animation in JS modules, not inline <script> in templates.
  • Pre-reveal states live in SCSS under .js (set before first paint by color-modes.js) so there is no flash of unstyled content; modules animate forward and hand elements back to CSS on complete.
  • Respect prefers-reduced-motion the same way existing modules do: write the final state immediately, or skip the effect.
  • Read durations / distances from CSS custom properties (motion & layout tokens) instead of hardcoding numbers in JS.
  • After structural DOM changes, call ScrollTrigger.refresh() if you add or remove triggers at runtime. main.js already refreshes on load and when webfonts are ready.