尚未收集仓库信息。
尚未检测到更新。GitHub 发布版本后会显示在这里。
3D shoe configurator built with React Three Fiber and Framer Motion
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Design a sneaker part by part, in real-time 3D, in the browser.
Pick a classic, click any panel, give it a real material and a color, print your own graphic on it, and leave with a share link, a saved design, a high-resolution render or the 3D model itself.
Live site · The lineup · Open the studio
Shoe Forge is a sneaker configurator in the spirit of Nike By You, built as a side project. It renders eight shoes in real time with physically based materials, lets you restyle every part, and keeps everything in the browser: there is no account, no backend database and no checkout. A whole design fits in a URL.
Two kinds of 3D models live side by side:
?d=), so any link rebuilds the
exact pair. Links are validated with a schema before loading..glb with your colors baked in.| Keys | Action |
|---|---|
Cmd/Ctrl K | Command menu |
Cmd/Ctrl Z | Undo |
Cmd/Ctrl Shift Z | Redo |
Cmd/Ctrl S | Save design |
[ and ] | Previous and next part |
1 to 6 | Camera views |
R | Surprise colorway |
Space | Turntable on or off |
Delete | Remove the selected graphic |
Esc | Cancel placing or deselect |
? | Show all shortcuts |
| Shoe | Brand | Category | Parts | Model type | |
|---|---|---|---|---|---|
| Air Force 1 '07 | Nike | Basketball | 12 | CG, one material per part | |
| Air Jordan 1 High | Jordan | Basketball | 7 | Photo scan, color regions | |
| Dunk Low | Nike | Court | 10 | CG, one material per part | |
| Gazelle | adidas | Terrace | 4 | Photo scan, color regions | |
| Suede Classic | PUMA | Court | 5 | Photo scan, color regions | |
| Old Skool | Vans | Skate | 8 | CG mockup, UV-island regions | |
| Chuck Taylor All Star High | Converse | Canvas | 8 | Photo scan, one material per part | |
| Forge Runner | Shoe Forge | Running | 8 | Built, one mesh per part |
| Studio | Shoe switcher |
|---|---|
The app is a static Next.js site with no server state. Everything a design needs travels in the URL or lives in the browser.
flowchart TB
subgraph Pages["Pages (app/)"]
direction LR
HOME["Home /"]
SHOES["Catalog /shoes"]
STUDIO["Studio /studio/[id]"]
GALLERY["Saved /gallery"]
end
subgraph State["Client state (lib/)"]
direction LR
PRODUCTS["Product data<br/>zod schema + lineup"]
STORE["Design store<br/>Zustand + undo"]
PERSIST["Persistence<br/>URL codec + IndexedDB"]
end
subgraph Render["3D renderer (components/three)"]
CANVAS["StudioCanvas<br/>React Three Fiber"]
MODELS["ProductModel / TintModel<br/>materials + recolor shader"]
EXTRAS["Decals, camera rig,<br/>lighting stage"]
end
subgraph Assets["Static assets (public/)"]
direction LR
GLB["GLB models"]
MASKS["Region masks"]
TEX["PBR textures"]
end
Pages --> State
State --> Render
CANVAS --> MODELS --> Assets
CANVAS --> EXTRAS
STORE <--> PERSIST
The asset pipeline runs offline and commits its output, so the deployed site only serves static files:
flowchart LR
SF["Sketchfab model<br/>(CC BY)"] --> IMP["import-shoes.mjs<br/>keep meshes, split materials,<br/>clean up PBR, optimize"]
IMP --> GLB["public/models/*.glb<br/>meshopt + WebP"]
IMP --> RM["region-masks.mjs<br/>k-means in Lab, UV,<br/>height and normal boxes"]
RM --> MASKS["public/models/*/mask-*.png"]
IMP --> MAN["manifest.json<br/>materials + region colors"]
MAN --> CFG["lib/products/lineup.ts"]
AMB["ambientCG (CC0)"] --> TEX["public/textures/"]
DEV["Running dev server"] --> SHOT["shoot-thumbs.mjs"] --> TH["public/shoes/*.webp"]
sequenceDiagram
participant U as Visitor
participant P as Studio page
participant S as Design store
participant C as 3D canvas
participant URL as Address bar
U->>P: Open /studio/air-jordan-1?d=...
P->>S: Decode and validate the design (zod)
S->>C: Parts, materials, colors, graphics
C->>C: Load GLB and masks, bake geometry, compile shaders
U->>C: Click a panel
C->>P: Part id under the pointer (mask lookup at the hit UV)
P->>C: Camera turns to the side the part faces
U->>P: Pick "Game Royal"
P->>S: setPartColor (one undo step)
S->>C: Shader target color eases in
S->>URL: Re-encode the design (replaceState)
Most brand models are a single mesh with one photographic texture, so "the Swoosh" is not a separate object. Shoe Forge makes those parts editable without repainting the texture.
scripts/region-masks.mjs clusters the texture's colors in Lab
space (k-means), merges clusters into the parts you would actually customize, and cleans up scan
noise with a majority filter and island removal. When color alone is not enough, it splits
regions by UV rectangles, by height on the shoe or by surface direction, using a map baked by
scripts/uv-attributes.mjs. The result is a few soft RGB mask textures per material.components/three/TintModel.tsx injects a fragment shader into
three.js's physical material. For each region it compares the texture's brightness with the
region's original average and applies the new color by ratio (bright sources) or by difference
(dark sources). That keeps folds, stitching and grain, so black suede can become white suede and
still look like suede.lib/three/facing.ts) tells the camera where to look
from.CG models with one material per part skip the masks and recolor whole materials with the same shader.
| Area | Choice |
|---|---|
| Framework | Next.js 16 (App Router), React 19, TypeScript in strict mode |
| 3D | three.js 0.186, React Three Fiber 9, drei 10 |
| Motion | GSAP 3 with ScrollTrigger, Lenis smooth scroll, Motion |
| Styling | Tailwind CSS 4 with design tokens, Archivo and Martian Mono |
| State | Zustand with zundo (undo/redo) and Immer |
| Validation | zod schemas for products and shared designs |
| Persistence | URL (lz-string) and IndexedDB (idb-keyval) |
| Asset pipeline | glTF Transform, meshoptimizer, sharp |
| Testing | Vitest, Playwright, axe-core |
| Hosting | Vercel, with Vercel Analytics |
Requirements: Node.js 22 or later and npm.
git clone https://github.com/hardikverma22/shoe-forge.git
cd shoe-forge
npm install
npm run dev
Open http://localhost:3000. The lineup is at /shoes, and each shoe's studio at
/studio/<id>, for example /studio/dunk-low.
All models, masks, textures and thumbnails are committed, so nothing needs to be downloaded to run the app. A Sketchfab token is only needed to re-import or add brand models:
cp .env.example .env.local
# then add SKETCHFAB_TOKEN=... to .env.local
| Command | What it does |
|---|---|
npm run dev | Development server |
npm run build | Production build |
npm start | Serve the production build |
npm run lint | ESLint |
npm run typecheck | TypeScript, strict mode |
npm test | Unit tests (Vitest) |
npm run test:e2e | End-to-end and accessibility tests (Playwright) |
npm run assets:model | Rebuilds the Forge Runner model from its source glTF |
npm run assets:textures | Re-downloads the CC0 PBR texture sets from ambientCG |
node scripts/import-shoes.mjs [id ...] | Downloads brand models from Sketchfab, cleans and optimizes them, and builds their region masks |
node scripts/shoot-thumbs.mjs <url> | Renders the catalog thumbnails from a running dev server |
node scripts/bake-swatches.mjs | Bakes the lit material swatches used across the site |
node scripts/trace-silhouette.mjs <image> | Traces a shoe render into SVG paths (used by the intro loader) |
node scripts/qa/region-map.mjs <url> <out> <id> | Paints every part a different color and shoots four views, to check part separation |
scripts/shoes.mjs with the model's id, which meshes to keep, and the mask
settings for any textured material.node scripts/import-shoes.mjs <id>. It writes the optimized model, the masks and a
manifest.json listing materials and region colors.lib/products/lineup.ts: parts (each a material or a region), allowed
materials, default colors from the manifest, camera views and researched colorways.node scripts/qa/region-map.mjs, render its thumbnail with
scripts/shoot-thumbs.mjs, and run npm test. The lineup test verifies every part against the
model's manifest and mask files.app/
page.tsx Home page
shoes/ Catalog with category filters
studio/[productId]/ The studio
gallery/ Saved designs
api/og/ Open Graph share image
render/[productId]/ Dev-only thumbnail renderer
components/
three/ StudioCanvas, ProductModel, TintModel, PartGraphics, CameraRig, Stage
studio/ Toolbar, ShoeSwitcher, PartRail, SidePanel and its panels, CommandMenu
landing/ Hero, IntroLoader, Tour, Materials, Colorways, Lineup, LandingScene
catalog/ ShoeGrid and model credits
site/, ui/ Header, footer, logo, primitives
lib/
products/ zod schema, the Forge Runner and the brand lineup
design/ Design store, URL codec, rules, colorways, saved designs
three/ Layout, anchors, part facing, scene and landing rig state
materials/ Material presets and texture cache
graphics/, export/ Text rendering, decal geometry, PNG and GLB export
scripts/ Asset pipeline and QA helpers
tests/
unit/ Vitest: schema, codec, rules, colorways, lineup integrity
e2e/ Playwright: landing, studio, catalog, mobile, accessibility
public/
models/ Optimized GLB models and region masks
textures/ PBR texture sets
shoes/ Catalog thumbnails
marks/ Original graphic marks
PRODUCT.md holds the product facts the design follows, DESIGN.md the design system, and
docs/DECISIONS.md records each departure from the original plan with its reason.
master, with preview deployments for pull requests.Shoe Forge is a fan project. It is not affiliated with, sponsored or endorsed by Nike, Jordan, adidas, PUMA, Vans or Converse. Their names and marks belong to their owners.