Restore React client source, add hall-to-hall navigation via painting influences grouped by movement, and update documentation. Co-authored-by: Cursor <cursoragent@cursor.com>
5.3 KiB
Art Gallery — architecture basics
Interactive virtual museum spanning art history: zoomable timeline, movement bands, 3D gallery halls, and painting influence graphs. See README.md for quick start.
Concept
The app is organised as a drill-down hierarchy:
- Timeline — historical eras (Ancient → Contemporary) with definite or fuzzy date boundaries.
- Movement bands — art movements aligned to the same time axis, each showing portrait thumbnails of key artists.
- 3D gallery — one personal hall per artist; paintings on the walls, open centre, single exit for influence-based navigation.
- Painting detail — full work in the centre, Influenced By on the left, Influenced on the right, link to artist biography.
All artwork images are stored locally under data/images/ — the UI never hot-links to Wikipedia or Commons at runtime (except optional on-demand fetch when a file is missing).
Stack
| Layer | Choice | Role |
|---|---|---|
| API | Node.js + Express 5 | REST API, static image serving, optional SPA hosting from client/dist |
| Database | PostgreSQL | Eras, movements, artists, paintings, influence edges |
| Frontend | React 19 + Vite 8 | SPA routing and UI |
| 3D | Three.js via @react-three/fiber, @react-three/drei |
Virtual gallery navigation |
| Data ingestion | Node scripts | Wikipedia summaries, Commons images, curated influence data |
Repository layout
Gallery/
├── server/ # Express API, DB pool, image service
├── client/ # React/Vite frontend
│ ├── src/ # Source (components, pages, 3D scene)
│ └── dist/ # Production build (served by API when present)
├── scripts/ # Seed, image fetch, catalog expansion
├── data/images/ # Local portraits and paintings (+ thumbs/)
├── db/ # SQL schema and migrations (when present)
├── Documentation/ # This folder
└── .env # DB and port config (not committed)
Runtime modes
Production-style (single process)
npm run server # http://localhost:3001
Serves /api/*, /images/*, and the built SPA from client/dist if it exists.
Development (two processes)
npm run dev:server # API on :3001
npm run dev:client # Vite on :5173, proxies /api and /images
Use the Vite URL during frontend work for HMR.
User navigation flow
flowchart TD
A[Home — timeline + movements] -->|scroll / drag / zoom| A
A -->|click portrait| B[Artist bio]
B -->|Enter Gallery| C[Artist hall — 3D]
C -->|click painting| D[Painting detail + influences]
C -->|exit doorway / E key| E[Path picker]
E -->|predecessors| C
E -->|successors| C
D -->|thumbnail left/right| D
D -->|artist link| B
B -->|Back| A
C -->|Back| A
Virtual gallery (3D halls)
Each artist has exactly one hall. The hall is a rectangular room sized to fit their catalog:
| Rule | Implementation |
|---|---|
| One hall per artist | VirtualGallery.tsx builds a single room from that artist’s paintings and periods |
| Paintings on walls | Works hang on the back, left, and right walls at eye level; periods are distributed across walls |
| Open centre | Floor and ceiling only — no columns, pedestals, or other centre objects |
| Single exit | One doorway on the front wall; walk to it or click it |
| Hall-to-hall travel | Exit opens a panel: Predecessors (left) and Successors (right), each grouped by art movement |
Controls: WASD / arrow keys to move; click a painting to open its detail view. At the exit, click the doorway or press E to choose the next artist.
Predecessors and successors come from the painting influence graph (painting_influences → other artists). Empty lists mean no influence edges are recorded yet for that artist — run npm run update-influences or extend seed data.
3D images use locally cached files only (galleryImageUrl in client/src/api/client.ts). Remote fetches are too slow for realtime WebGL textures; call POST /api/artists/:id/preload-images before entering a hall to link disk files.
Key design decisions
- Timeline bounds derive from the earliest art movement start year, not ancient-era metadata alone, so the default view opens where catalogued content begins.
- Movement filtering on zoom only shows movements that have at least one artist active in the visible year range.
- One hall per artist keeps navigation predictable: enter from the timeline or bio, leave via the single exit or back button.
- Influence-based hall links connect artists through documented painting-to-painting relationships, grouped by movement at the exit.
- 3D gallery images use locally cached files only; slow remote fetches would break realtime rendering.
- Influence data is stored as directed edges between paintings, with optional citation fields (source author, quote, URL) for art-historical references.
Related docs
| Document | Contents |
|---|---|
| setup.md | Install, database, npm scripts |
| DB_structure.md | Tables and relationships |
| API.md | REST endpoints |
| data-and-images.md | Image pipeline and seeding |