Luxury Focus

UserBigcatgj
原作者: motionsites
原文链接
2026/8/17
通用
E-commerce

提示词内容

Recreate "SCULPTED BY TIME" Luxury Jewelry Scroll Experience

Build a single-page React + TypeScript + Vite landing page for a luxury jewelry brand. It is a **scroll-driven cinematic experience**: the page is very tall, and scrolling scrubs through two background videos while editorial text fades/blurs away and product panels slide in. Use **Tailwind CSS v4** (via `@tailwindcss/vite`) and `lucide-react` for icons. Everything lives in a single `src/App.tsx` component. No backend / no data persistence is needed.

## Stack & setup
- Dependencies: `react@19`, `react-dom@19`, `vite@6`, `@vitejs/plugin-react`, `@tailwindcss/vite`, `tailwindcss@4`, `lucide-react`, `motion`.
- `src/main.tsx` renders `<App />` into `#root`.
- `index.html` has `<div id="root"></div>` and loads `/src/main.tsx`.

## Fonts (src/index.css)
```css
@import url('https://fonts.googleapis.com/css2?family=Instrument+Serif:ital,wght@0,400;1,400&family=Manrope:wght@200;300;400;500;600;700;800&display=swap');
@import "tailwindcss";

@theme {
  --font-serif: "Instrument Serif", serif;
  --font-sans: "Manrope", sans-serif;
}
```
- Serif display font: **Instrument Serif** (`font-serif`).
- Sans UI font: **Manrope** (`font-sans`).

## Asset URLs (use exactly)
- Background video 1 (plays during first 40% of scroll):
  `https://res.cloudinary.com/dbfd996z4/video/upload/q_auto/f_auto/v1781009724/11111111_gvewuj.mp4`
- Background video 2 (plays during second half):
  `https://res.cloudinary.com/dbfd996z4/video/upload/q_auto/f_auto/v1781009724/2222222_x4qpet.mp4`
- Hero product PNG (ring): `https://res.cloudinary.com/dbfd996z4/image/upload/q_auto/f_auto/v1781009782/rng_awymkj.png`
- Panel product 1 (earrings): `https://res.cloudinary.com/dbfd996z4/image/upload/q_auto/f_auto/v1781017114/202606091756_msbh8b.jpg`
- Panel product 2 (ring): `https://res.cloudinary.com/dbfd996z4/image/upload/q_auto/f_auto/v1781019866/2606091843_kfonxp.jpg`

(Note: there is no CloudFront URL in this project — all media is served from Cloudinary at the `dbfd996z4` account. The `/public/main` and `/public/second` JPG frame sequences exist as fallbacks but the live page scrubs the two Cloudinary MP4s, not the JPGs.)

## Color & theme
- Page background: `#020202` (near-black), text white.
- Signature accent (titles, progress bar, hover states, cart dot): `#FBFF8D` (luminous pale chartreuse-yellow).
- Slide-in product panel background: `#FAF9F5` (warm off-white), text `#121212`; muted greys `#8E8B84`, `#73716C`, `#E5E5E2`.
- NO purple/violet anywhere.

## Layout structure (single root `div`, `h-[650vh]`, `bg-[#020202]`, `overflow-x-hidden`, `antialiased`, `font-sans`)

### 1. Fixed background video stage (`fixed inset-0 z-0`, pointer-events-none)
- Two `<video>` elements stacked absolutely, `object-cover`, `muted playsInline preload="auto"`.
- Video 1 opacity `0.85` when `progress < 0.48`, else `0`; Video 2 opacity `0.85` when `progress >= 0.48`, else `0`. Cross-fade with `transition-opacity duration-700 ease-in-out`.
- A hidden `<canvas>` (kept in DOM, `display:none`).
- Three gradient overlays for typography contrast: top (`h-44`, black 85%→transparent), bottom (`h-56`, black 90%→transparent), left (`w-1/2`, black 40%→transparent, only `lg:block`).

### 2. Top progress bar (`fixed top-0 left-0 h-[2.5px] bg-[#FBFF8D] z-50`)
- Width = `${progress * 100}%`, `transition-all duration-75`, pointer-events-none.

### 3. Editorial overlay (`fixed inset-0 z-10`, flex column space-between, padding `p-6 md:p-10 lg:p-12`)
- `pointerEvents: 'none'` when `progress > 0.45`; `visibility: hidden` when `progress >= 0.45`.
- **Header** (`flex justify-between items-start`):
  - Left column (`flex flex-col gap-10`): a 48×48 white brand crest **SVG** (5-petal abstract floral logo — provide the multi-path SVG), and 40px below it a sub-header: `<h3>` "Contemporary Luxury For The / Discerning Minimalist" (semibold, 12-13px, tracking -0.03em) + a `<p>` (11px, white/50, max-width 260px): "Exclusive creations tailored for true aesthetes. We forge more than simple ornaments; we build tactile artifacts of your personal legacy."
  - Right nav (`flex items-center gap-5..8`, 13px white/70): links **Collections, Atelier, Our story, Contact**, each with animated underline-on-hover (`after:` pseudo growing from w-0 to w-full) and `hover:scale-105`. Then a vertical separator, a **User** icon link, and a **ShoppingBag** button (with a pulsing `#FBFF8D` 6.5px dot badge). The bag button smooth-scrolls to the very bottom of the page.
- **Hero main** (`grid grid-cols-1 lg:grid-cols-12`, items-end):
  - Left (cols 1-7): giant serif headline `#FBFF8D`, uppercase, `leading-[0.88]`, fluid `fontSize: clamp(2.5rem, 5.6vw, 7.5rem)`, three lines each as own div: "&nbsp;&nbsp;&nbsp;&nbsp;*SCULPTED*" (italic), "BY TIME. WORN", "BY *YOU*" (italic). Below it two manifesto `<p>` blocks (11px white/50, width 260px) — text: "We craft modern jewelry that speaks volumes through silence..." and "Every piece acts as a personal manifesto...".
  - Right (cols 8-12, max-w-240px): product caption block — small label "Abyssal Silver Ring", `<h2>` "18K White Gold & Rough Onyx", a 10.5px description; then a transparent product card (`aspect-[4/5]`, `hover:scale-[1.04]`) holding the ring PNG (`object-contain`, `group-hover:scale-105`); then a centered serif price "$1,850" that turns `#FBFF8D` on group hover.

### 4. Slide-in product sheet (`fixed top-0 left-0 h-full w-full sm:w-[600px] lg:w-[648px] bg-[#FAF9F5] text-[#121212] z-30`)
- Transform: `translate-x-0` when open else `-translate-x-full`, `transition-transform duration-[1100ms] ease-[cubic-bezier(0.16,1,0.3,1)]`, shadow `12px 0 45px rgba(0,0,0,0.22)`, `overflow-y-auto`.
- Open when `progress >= 0.40 && progress < 0.50` (first card) OR `progress >= 0.90` (second card).
- Top-left **BACK TO SERIES** button (ArrowLeft icon, uppercase, tracking 0.16em) that smooth-scrolls back: to 82% if `progress >= 0.90`, else to 35%.
- Centered product header: category label (uppercase, tracking 0.15em, `#8E8B84`), serif `<h2>` title, 12px description `#73716C`; then a centered product image (`max-w-[460px]`).
- Footer transaction row (border-top, full-bleed via negative margins): a black **ADD TO ATELIER BAG** button (`h-[50px]`, uppercase tracking 0.15em), a `#E5E5E2` quantity stepper (− value +), and a large serif dynamic price `${price * quantity}`.
- **Dynamic product data** driven by `isSecondCard` (`progress >= 0.90`):
  - Second card: category "Atelier Core Edition", title "Sterling Silver Sculpture Ring", price 1350, image = ring JPG, with the sculpture description.
  - Otherwise: category "Aura Fine Earrings", title "18K White Gold & Pink Sapphire", price 1850, image = earrings JPG, with the drop-stud description.
  - Reset `quantity` to 1 whenever the active product title changes.

## Scroll & animation engine (the core)
Use refs (not state) for animation values to avoid re-renders; only `progress` and `quantity` are React state.

- **State refs:** `targetScrollFractionRef`, `currentScrollFractionRef`, `targetVideoRatioRef`, `currentVideoTimeRef`, `targetVideoSecondRatioRef`, `currentVideoSecondTimeRef`, `targetFrameRef`, `currentFrameRef`. `totalFrames = 480`.
- **Scroll listener:** compute `scrollTop / (scrollHeight - clientHeight)`, clamp 0–1, store in `targetScrollFractionRef`. Passive listener; also run once on mount and once after a 500ms timeout.
- **requestAnimationFrame loop** (`smoothUpdate`):
  1. Lerp `currentScrollFraction` toward target by factor **0.05** (snap when very close) — gives a weighted, cinematic, "catch-up" feel. `setProgress(currentScrollFraction)`.
  2. Map `activeProgress` to phases:
     - `<= 0.40`: ratio = p/0.40 → video1 ratio = ratio, video2 = 0, frame = 1 + ratio*239.
     - `0.40–0.50`: video1 = 1.0, frame = 240 (hold — first panel open).
     - `0.50–0.90`: video1 = 1.0, video2 ratio = (p-0.50)/0.40, frame = 241 + ratio*239.
     - `> 0.90`: both = 1.0, frame = 480 (second panel open).
  3. Scrub each video by lerping `currentVideoTime` toward `targetRatio * video.duration` by factor **0.08**, and set `video.currentTime` — **but only when `!video.seeking`** (skip issuing a new seek while the browser is still painting the previous frame, to prevent stutter). Same guard for the second video.
  4. Lerp `currentFrameRef` toward `targetFrameRef` by 0.08, clamped to [1, 480].
  5. Re-request the frame; cancel on cleanup.

## Stagger helper (`getStaggerStyle(start, end)`)
Maps `progress` within a [start,end] window to a fade-out: `opacity = 1 - ratio`, `translateY = -75 * ratio`, `filter: blur(${ratio*16}px)`, `willChange`, and a `cubic-bezier(0.16,1,0.3,1)` 0.35s transition; `pointerEvents: 'none'` once opacity < 0.15. Apply staggered windows to each editorial element so they melt upward and blur away as you scroll (logo 0.00–0.12, subheader 0.06–0.18, nav 0.03–0.15, title lines 0.09/0.12/0.15 → +0.11, manifesto 0.18/0.21, right caption 0.14–0.25, card 0.18–0.29, price 0.20–0.31).

## Embedded `<style>` extras
- `@keyframes scrollLine`.
- Custom dark webkit scrollbar (6px, track `#020202`, thumb white/15, hover `#FBFF8D`/40).
- Media query `(max-height:780px) and (min-width:1024px)`: tighten `#sculpted-title` margin and `#product-image-card` padding.

## Behavior summary
Scrolling 0→100% of the 650vh page: hero text melts away → video 1 scrubs forward → first earrings panel slides in (~40-50%) → video 2 scrubs → second ring panel slides in (~90%+). The ShoppingBag button jumps to the final panel; the panel BACK button scrolls back into the video sequence. All motion is buttery via double-lerp (scroll smoothing 0.05 + media smoothing 0.08) and the `!seeking` seek guard.

暂无效果展示

作者尚未提供生成效果案例;新的公开提示词需要至少添加一个案例。

想要不同效果?只改几处即可

AI 自动找出可替换的部分(主体/风格/场景),填入想要的值,其余保持不变

提示词广场登录