back to lab
Hello GSAP
A springy square entrance using the site's own motion tokens — the lab's hello world.
preview
function Sketch() { const ref = useRef(null) const [round, setRound] = useState(0) useEffect(() => { const ctx = gsap.context(() => { gsap.from(".box", { y: 40, opacity: 0, rotation: -12, ease: EASE.jelly, duration: 0.9, stagger: STAGGER.base, }) }, ref) // Cleanup keeps re-runs leak-free: react-live re-evaluates on every edit. return () => ctx.revert() }, [round]) return ( <div ref={ref} className="flex h-full min-h-56 flex-col items-center justify-center gap-6" > <div className="flex gap-4"> <div className="box h-14 w-14 rounded-sm border-2 border-border bg-accent-cyan shadow-hard" /> <div className="box h-14 w-14 rounded-sm border-2 border-border bg-accent-pink shadow-hard" /> <div className="box h-14 w-14 rounded-sm border-2 border-border bg-accent-lilac shadow-hard" /> </div> <button type="button" onClick={() => setRound((r) => r + 1)} className="rounded-sm border-2 border-border bg-brand px-4 py-1.5 font-mono text-xs font-bold uppercase tracking-wider text-on-brand shadow-hard transition-all hover:shadow-hard-sm hover:translate-x-[1px] hover:translate-y-[1px] active:translate-x-[2px] active:translate-y-[2px] active:shadow-none" > replay </button> </div> ) } render(<Sketch />)
what's in scope
Sketches run with these values already available — no imports needed. Anything Tailwind can style, gsap can move.
- react
- React
- useState
- useEffect
- useRef
- useMemo
- useCallback
- useLayoutEffect
- motion
- gsap
- EASE
- DURATION
- STAGGER
- utils
- cn
- icons
- ArrowRight
- Check
- Heart
- Moon
- Sparkles
- Star
- Sun
- Zap