Inspiration
We were inspired by iconic, high-end interactive product journeys (such as Apple hardware reveals and award-winning boutique studios like WildCrumb), where scrolling through a website feels like scrubbing through a physical transformation in real time.
Most e-commerce and food brand websites rely on static grids and flat photo cards. We asked ourselves: What if shopping for artisanal pastries felt as tactile and immersive as watching the lamination of 81 flaky pastry layers expand inside a Parisian hearth oven?
We set out to build an interactive web experience that combines frame-accurate 60fps continuous scroll-scrubbing with dynamic spatial typography, an interactive custom pastry atelier, and zero video decode lag.
What it does
Crussant (https://crussant.vercel.app/) is a cinematic, scroll-driven web experience for an artisanal bakery:
- Continuous 3D Scroll Scrubbing: Scrubbing vertically controls the continuous transformation of raw French laminated dough into golden baked viennoiserie across an 80-frame WebP pipeline with instantaneous forward and reverse responsiveness.
- Parametric Spatial Typography: Rather than hiding the scene behind clunky frosted-glass cards, bare uppercase typography floats directly over the visual composition across four choreographed phases (The Perfect Bake, Time Is An Ingredient, Purest Provenance, and Taste The Tradition).
- Interactive Atelier & Box Builder: A live configurator that allows customers to assemble custom pastry boxes (
S: 4-Pack,M: 6-Pack,L: 12-Pack), select finishing artisanal glazes (Normandy Honey Glaze, Valrhona Chocolate, Toasted Almonds), and observe real-time price updates on a live platter. - Scroll-Driven 3D Rotational Hook: A closing interactive CTA featuring an artisanal slate disc that smoothly rotates clockwise on scroll.
- Seamless Floating Navigation & Full Accessibility: High-DPI canvas rendering, active section tracking, and automatic
prefers-reduced-motionfallbacks.
How we built it
- Frontend Core: Built with React 19, TypeScript, and Vite 8 for instant HMR and lightweight bundle size.
- In-Memory Frame Pipeline: Engineered a custom parallel preloader (
framePreloader.ts) that loads 80 high-resolution WebP frames into an in-memoryHTMLImageElement[]cache, bound to a deterministic loading screen. - Canvas Cover Engine: Instead of DOM
<img>swapping, we implemented a hardware-accelerated 2D<canvas>that computesobject-fit: covermath dynamically on every resize and device pixel ratio (dpr). - Normalized Scroll Engine: A custom React hook (
useScrollSequence.ts) translates scroll distance into a normalized float ($0.0 \rightarrow 1.0$) and maps it directly to array indices ($O(1)$ lookup time: $< 1\text{ms}$). - Motion & Typography: Mathematical trapezoidal curves for smooth parametric opacity/translation fades, combined with CSS custom property design tokens in a warm amber-orange brand palette (
#FF8A1E). - Deployment: Deployed on Vercel with optimized static asset caching.
Challenges we ran into
- The
<video>Seeking Stutter: Our initial prototype attempted to drive animation usingHTMLVideoElement.currentTime. On desktop and mobile, hardware decoders seek via temporal GOP keyframes, causing 100ms–300ms stuttering and dropped frames on rapid reverse scrolling. We solved this by transitioning to an in-memory WebP image sequence rendered synchronously onto a 2D canvas buffer. - Preventing Memory Thrashing & Layout Reflows: Swapping images directly in the DOM caused paint flashes and layout recalibration. Moving to a single persistent
<canvas>context eliminated all DOM thrashing. - Spatial Text Alignment on Mobile Viewports: Because the text overlays float over specific negative space in the croissant background (left side, right side, center), wide screens and vertical phone viewports required adaptive parametric bounds and clamp-based fluid typography (
clamp()) to prevent text from overflowing or obscuring the subject.
Accomplishments that we're proud of
- Zero-Latency Scrubbing at 60 FPS: Achieving true frame-by-frame bi-directional scrub responsiveness with under 1ms lookup latency.
- Uncluttered, Card-Free Aesthetic: Successfully executing the "WildCrumb" layout pattern where text elements interact with the scene rather than sitting inside boxed containers.
- Lightweight Memory Footprint: Bundling two 40-frame sequence transitions into an optimized ~6MB total payload without compromising visual fidelity.
- Flawless Live Deployment: Delivering a fast, interactive experience live on Vercel at https://crussant.vercel.app/.
What we learned
- Canvas vs. Video Tradeoffs: Video is great for linear playback, but for interactive, user-driven scrub physics, preloaded frame sequences on
<canvas>provide unmatched control and smoothness. - Choreography Engineering: Timing UI copy to scroll percentages requires mathematical fade curves ($fade-in \rightarrow rest \rightarrow fade-out$) rather than simple scroll triggers to make the storytelling feel organic.
- Design Systems Matter: Restricting color tokens to curated HSL-tailored amber-orange accents (
#FF8A1E) and rich dark backgrounds (#080604) elevated the feel from a basic app to a luxury boutique brand.
What's next for Crussant
- Dynamic 3D WebGL / Three.js Shaders: Introducing interactive lighting and crumb physics that react to cursor movement and gyroscopic tilt on mobile.
- Full E-Commerce Checkout & Batch Booking: Integrating Stripe for real-time pickup reservations synced with morning batch bake timers.
- Reusable NPM Package: Extracting our canvas scroll-scrub engine and parametric text hook into an open-source React component library (
@scrub-flow/react) for developers building product showcases.
Log in or sign up for Devpost to join the conversation.