Spurlock Studios
Contact
Motion Systems That Ship: GSAP, Scroll, and the Budget That Keeps Them Alive

Award reels lie. They compress a site into a silent 1080p capture on a plugged-in laptop. Production tells the truth: mid-range Androids, hotel wifi, Safari quirks, and users who never asked for your scrubbed timeline. This spoke is the motion system I use so cinematic sites still feel intentional after they leave Figma — and after they meet Core Web Vitals. It sits under the pillar Websites That Feel Like Films.

The production contract

Before any tween, agree on a contract:

  1. Critical content is visible with JavaScript disabled or delayed.
  2. Motion uses transform and opacity unless there is a written exception.
  3. Every ScrollTrigger and listener has a teardown path.
  4. prefers-reduced-motion: reduce is a designed variant, not animation: none sprinkled late.
  5. The motion budget is numbered. Unlimited motion is how Lighthouse dies.

If a stakeholder cannot accept those five lines, you do not have a motion problem. You have a scope problem.

GSAP for marketing sites

GSAP remains the right tool when you need timeline precision, scroll scrubbing, and cleanup that does not leave zombie triggers. On marketing sites I almost always wrap work in gsap.context so React/Astro islands can revert() on unmount.

useEffect(() => {
  const ctx = gsap.context(() => {
    gsap.from(".hero-line", { y: 24, opacity: 0, stagger: 0.08, duration: 0.7, ease: "power3.out" });
  }, rootRef);
  return () => ctx.revert();
}, []);

What to animate

Cheap and preferred:

  • x, y, scale, rotate, opacity
  • clip-path carefully, on small regions, tested on low-end devices
  • SVG stroke draws when the path count is sane

Expensive and usually refused:

  • animating width, height, top, left
  • continuous filter: blur() on large layers
  • box-shadow pulses on many elements
  • scroll-linked blur/brightness on full-bleed heroes

Scroll: earn every pin

Pinned sections are cinematic and costly. Cap homepage pins. Prefer short pins that teach one idea over multi-scene epics that trap users on mobile. Always test rubber-banding and address-bar show/hide on iOS — scroll math that is perfect in desktop Chrome often jitters on phones.

When a pin is mandatory, keep the pinned content light: fewer images, no autoplay video, no nested scrollers.

Production motion design on the web

Load order

Ship the hero in its final visual state in HTML/CSS. Let motion enhance. If the headline starts at opacity: 0 in CSS and only GSAP reveals it, a failed chunk load produces a blank brand. That is not an edge case; that is a launch incident waiting.

will-change is a loan

Promote layers for active tweens, then release. Blanket will-change: transform across the page creates memory pressure on the exact devices you are trying to protect. GSAP handles a lot of this if you stay inside its APIs; raw CSS often does not.

Shared easing, shared duration families

Pick two easings and three duration steps for the whole site. Random easings per section make the brand feel accidental. Consistency reads as craft even when individual moves are simple.

Framer when it is enough

Framer is a strong home for component-native motion when the team iterates in design tools and the page count stays in marketing territory. Use it when:

  • Designers own interaction timing
  • You need fast marketing iteration
  • The site is not fighting for every Lighthouse point under heavy CMS complexity

Reach for GSAP-in-code when you need scrubbed production timelines, complex cleanup across route changes, or a static shell (Astro and friends) with islands. Webflow interactions cover a wide middle; escalate when the interaction graph outgrows the panel UI.

Budget template you can paste into a kickoff

ItemCapKill criteria
Hero entrance≤1.2s totalCompetes with LCP
Section revealShared 0.5–0.7sCauses layout shift
Scrubbed scene0–1 / pageJank on mid Android
Cursor / trail effectsDesktop onlyBreaks focus or battery
Background videoClick-to-play defaultAutoplay + sound risk

Review the budget in the same meeting as the mood board. Motion added after visual lock is how scope explodes.

Reduced motion as a first-class cut

Author the static composition first. Then add motion for no-preference. In GSAP:

const mm = gsap.matchMedia();
mm.add("(prefers-reduced-motion: reduce)", () => {
  gsap.set(".hero-line", { clearProps: "all", opacity: 1, y: 0 });
});
mm.add("(prefers-reduced-motion: no-preference)", () => {
  // timelines
});

QA both. If the reduced-motion build looks unfinished, the motion was hiding weak layout.

Motion and conversion share a fold

Motion that delays comprehension hurts conversion. If the primary CTA arrives 1.5 seconds after a choreographed logo draw, you traded bookings for a portfolio clip. Sequence meaning first: brand and offer readable immediately, then presence animations that do not rearrange the reading order.

Pair with Above the Fold That Works when the fold itself is unclear. Pair with Lighthouse 90+ Without Killing the Design when scores collapse after the motion pass.

Tooling reality check

Teams ask for “Awwwards motion” with a brochure budget and a Webflow-only maintainer. Be explicit:

  • CSS transitions: enough for many brand sites
  • Framer motion: enough for most marketing narratives
  • GSAP + ScrollTrigger: when scrubbing and timeline authorship are the product
  • WebGL / shaders: rare, expensive, and first on the cut list when phones stutter

Related field note: Motion That Survives Production.

QA checklist before you call motion done

  • Mid-tier Android, Chrome, throttled 4G
  • iPhone Safari, notch devices
  • Keyboard only: no focus traps from animation overlays
  • Hard refresh with cold cache
  • Navigate away and back if SPA-like; watch for duplicate triggers
  • Lighthouse mobile after motion, not before
  • Reduced-motion OS setting verified

Where this fits the sprint

In a Spurlock Studios website sprint, motion is never the first deliverable. Fold and static composition come first. Motion is the pass that adds presence once the conversion job is true. Explore /websites or book a sprint at /contact?intent=websites-sprint.

Sequencing motion across a marketing narrative

Think in scenes, not in “can we animate this div.” A homepage might be five scenes: arrival, offer, proof, work, contact. Each scene gets at most one signature move. Shared section reveals can repeat; signature moves should not. When every block has a unique choreography, the brand feels busy rather than directed.

I storyboard motion in a simple table during kickoff:

SceneSignature moveFallback (reduced motion)
ArrivalLine rise + soft dim on plateStatic composition
OfferAccent underline drawInstant underline
ProofStaggered quote opacityFull opacity list
WorkHorizontal drag or simple gridGrid, no drag
ContactFocus on formForm visible

If the table is empty because nobody can name the move, skip motion for that scene.

GSAP plugins and dependency discipline

Marketing sites rarely need the full plugin zoo. ScrollTrigger covers most scroll needs. Flip is powerful and easy to misuse. Draggable is great for work boards and dangerous for accessibility if keyboard equivalents are missing. Observer can replace brittle wheel hacks.

Pin versions. A plugin upgrade mid-project that changes default scrub smoothing will burn hours. Keep a short internal note: GSAP version, plugins used, and where contexts live in the codebase.

Competing with video culture without shipping a film file

Clients often want “cinematic” and arrive with a 40MB hero MP4. Prefer:

  • High-quality still + subtle motion (ken burns via transform, grain overlay, light leaks as CSS/SVG)
  • Short looping fragments only when file weight is controlled and playback is intentional
  • Poster-first video with click-to-play for anything with narrative audio or long runtime

A still that feels directed beats a soft autoplay video that heats phones and fails LCP.

Collaboration between design and engineering

Hand off motion as specs, not vibes:

  • Trigger (load, inview, scroll progress, hover, click)
  • Properties (x/y/opacity/scale)
  • Duration and easing tokens
  • Stagger values
  • Mobile differences
  • Reduced-motion behavior

Framer collapses some of that handoff when designers build the motion themselves. On custom stacks, written specs prevent the “make it cooler” loop that never ends.

Failure modes I have already paid for

  • Headline hidden until a 180kb animation library downloads
  • Pin + sticky header fighting for the same space
  • Lenis/smooth-scroll libraries stacked on ScrollTrigger without shared authority
  • Horizontal sections that trap focus and break back-gesture expectations
  • Timeline labels nobody documented, so the next engineer is afraid to touch production

Document the motion system like any other design system: tokens, recipes, and bans.

Connecting motion to the wider site system

Motion should reuse the same accent color, type rhythm, and spacing as the static system. If the brand accent is reserved for CTAs, do not also spray it across every tween highlight. Restraint is what makes the one accent hit feel expensive. For the larger authorship frame, return to Websites That Feel Like Films.

Shipping checklist for the motion pass

Before merge: confirm hero text is in the HTML end-state; confirm only transform/opacity in new timelines; confirm every gsap.context has revert; confirm reduced-motion path; confirm Lighthouse mobile did not regress more than the agreed budget; confirm no scroll library conflict; confirm marketing OK signed the motion budget table. If any box is unchecked, the pass is not done — even if the capture video looks perfect.

FAQ

Is GSAP still worth it for marketing sites in 2026?

Yes when you need precise timelines, scroll control, and reliable cleanup. For lighter marketing motion, CSS or Framer may be enough. Choose by complexity and who maintains the site, not by portfolio fashion.

How do I keep scroll animations from destroying performance?

Limit pins, stick to transform/opacity, keep pinned DOM light, test on real phones, and tear down triggers on unmount. One earned scrubbed scene beats five decorative ones.

Should the hero animate on load?

Optionally, and never in a way that hides text before JS runs. Ship the final hero state in HTML/CSS, then enhance. If the animation fails, the brand must still be readable.

How do I handle prefers-reduced-motion?

Design a complete static variant. Do not leave elements stuck invisible. Use matchMedia (GSAP) or equivalent branches so reduced motion is intentional.

When should I use Framer instead of hand-coded GSAP?

Use Framer when designers own interaction and the project is marketing-page centric. Use hand-coded GSAP when you need production scrubbing, custom routing cleanup, or a performance-first static architecture.

What is a sane motion budget for a homepage?

One hero entrance, shared section reveals, at most one scrubbed scene, micro-interactions on controls, and almost no ambient loops. Write the caps down before design starts.

Start a sprint