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>
112 lines
5.3 KiB
Markdown
112 lines
5.3 KiB
Markdown
# Art Gallery — architecture basics
|
||
|
||
Interactive virtual museum spanning art history: zoomable timeline, movement bands, 3D gallery halls, and painting influence graphs. See [README.md](../README.md) for quick start.
|
||
|
||
## Concept
|
||
|
||
The app is organised as a **drill-down hierarchy**:
|
||
|
||
1. **Timeline** — historical eras (Ancient → Contemporary) with definite or fuzzy date boundaries.
|
||
2. **Movement bands** — art movements aligned to the same time axis, each showing portrait thumbnails of key artists.
|
||
3. **3D gallery** — one personal hall per artist; paintings on the walls, open centre, single exit for influence-based navigation.
|
||
4. **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
|
||
|
||
```text
|
||
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)
|
||
|
||
```bash
|
||
npm run server # http://localhost:3001
|
||
```
|
||
|
||
Serves `/api/*`, `/images/*`, and the built SPA from `client/dist` if it exists.
|
||
|
||
### Development (two processes)
|
||
|
||
```bash
|
||
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
|
||
|
||
```mermaid
|
||
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](setup.md) | Install, database, npm scripts |
|
||
| [DB_structure.md](DB_structure.md) | Tables and relationships |
|
||
| [API.md](API.md) | REST endpoints |
|
||
| [data-and-images.md](data-and-images.md) | Image pipeline and seeding |
|