Skip to content

Craft · 試作

Craft

A lab of small, self-contained interactions — the kind I build to get a feel exactly right: the slide, the spring, the way a thing should respond to your hand. Every one runs at 60fps, works on touch and keyboard, and you can open the build breakdown to see how.

04 experiments · interactive & inspectable

Experiments

Liquid Glass nav

One shared spotlight pill glides under whatever you hover or focus, then settles back on the selected item — a single animated element, not a fade per link.

  • GSAP
  • Shared element
  • Keyboard
Build breakdown
  • The pill is one absolutely-positioned span; on hover/focus I measure the target button's offsetLeft + width and tween x/width with power3.out (~280ms — under the 300ms perceived-instant ceiling).
  • Only transform and width animate — no layout per frame — so it holds 60fps.
  • Focus drives the exact same motion as hover, and Enter/Space selects; the pill re-aligns on resize.
  • Reduced motion → the pill jumps instantly instead of tweening.

Drag-to-dismiss sheet

A bottom sheet you can fling away. Drag past 40% of its height — or flick it down fast — to dismiss; anything less springs back. Pulling up rubber-bands.

  • GSAP
  • Pointer Events
  • Gesture
Build breakdown
  • Dragging is hand-rolled on Pointer Events with setPointerCapture, so the gesture survives the pointer leaving the grabber (mouse + touch alike).
  • Release reads distance and velocity (px/ms from event timestamps): past the threshold it dismisses, otherwise GSAP springs it back to rest.
  • Upward pulls past rest are damped to 25% for a rubber-band feel; touch-action:none stops the page scrolling under the drag.
  • Keyboard users get an explicit Close button and Escape; focus moves into the sheet on open and back to the trigger on close.

Origin-aware popover

The panel grows out of the button that opened it — its transform-origin points at the trigger's centre, so it unfolds from the right spot every time.

  • GSAP
  • transform-origin
  • A11y
Build breakdown
  • On open I measure the trigger, clamp the panel within the stage, and set transform-origin to the trigger's centre in px.
  • Mouse opens with a quick scale(0.96)+fade from that origin; keyboard opens instantly — animating keyboard-driven UI is disorienting.
  • Positioning + the tween run in a GSAP layout effect, so the panel never flashes unpositioned.
  • Escape closes and restores focus to the trigger; an outside pointerdown closes without stealing focus.

Click to copy

Click-to-copy email

Tap the address and it's on your clipboard — the icon pops to a check and the button confirms 'Copied', then settles back. The same control ships on the contact page.

  • GSAP
  • Clipboard API
  • A11y
Build breakdown
  • Copy goes through the async Clipboard API, with a hidden-textarea + execCommand fallback for older or insecure contexts so it still works everywhere.
  • On success the icon swaps Copy → Check and pops with a GSAP back.out(3) scale; the address itself stays select-all for manual copy.
  • The result is announced through a polite aria-live status region, so screen-reader users hear 'Copied' without focus moving.
  • Reduced motion → the icon swaps instantly with no pop.