Redesign 3D gallery as single hall per artist with exit navigation.
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>
This commit is contained in:
1 parent
44d3d4359a
commit
08f99d7a29
25 files changed
+2954
-218
No files matched your search
@@ -92,6 +92,41 @@ Full artist profile for the bio page and 3D gallery entry.
|
||||
|
||||
---
|
||||
|
||||
## `GET /api/artists/:id/navigation`
|
||||
|
||||
Related artists for hall-to-hall navigation at the exit doorway. Derived from `painting_influences`:
|
||||
|
||||
- **Predecessors** — artists whose works influenced this artist’s paintings.
|
||||
- **Successors** — artists whose works were influenced by this artist’s paintings.
|
||||
|
||||
Both lists are grouped by art movement and exclude the current artist.
|
||||
|
||||
**Response**
|
||||
|
||||
```json
|
||||
{
|
||||
"predecessors": [
|
||||
{
|
||||
"movement_id": 4,
|
||||
"movement_name": "Early Renaissance",
|
||||
"movement_color": "#B8860B",
|
||||
"artists": [
|
||||
{
|
||||
"id": 12,
|
||||
"name": "Domenico Ghirlandaio",
|
||||
"birth_year": 1448,
|
||||
"death_year": 1494,
|
||||
"portrait_path": "portraits/Domenico_Ghirlandaio.jpg"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"successors": []
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## `POST /api/artists/:id/preload-images`
|
||||
|
||||
Fast local scan: links paintings to files already on disk. Does **not** download from the internet (safe to call before opening the 3D gallery).
|
||||
@@ -146,6 +181,7 @@ The React client wraps these endpoints in `client/src/api/client.ts`:
|
||||
| `api.getTimeline(start, end)` | `GET /api/timeline` |
|
||||
| `api.getArtists(...)` | `GET /api/artists` |
|
||||
| `api.getArtist(id)` | `GET /api/artists/:id` |
|
||||
| `api.getArtistNavigation(id)` | `GET /api/artists/:id/navigation` |
|
||||
| `api.getPainting(id)` | `GET /api/paintings/:id` |
|
||||
| `preloadArtistImages(id)` | `POST /api/artists/:id/preload-images` |
|
||||
| `imageUrl(path)` | `/images/<path>` or placeholder |
|
||||
|
||||
@@ -114,6 +114,8 @@ Directed edges: *this painting* was influenced by *that painting*.
|
||||
|
||||
Unique constraint on `(painting_id, influenced_by_painting_id)`.
|
||||
|
||||
Used by the 3D gallery exit panel: predecessors are artists of `influenced_by_painting_id` works; successors are artists of paintings influenced by this artist’s works (see [API.md](API.md#get-apiartistsidnavigation)).
|
||||
|
||||
## Indexes
|
||||
|
||||
- `artists(movement_id)`, `artists(century)`
|
||||
|
||||
+26
-3
@@ -8,7 +8,7 @@ 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** — classic hall environment; paintings grouped by the artist’s creative periods.
|
||||
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).
|
||||
@@ -63,19 +63,42 @@ Use the Vite URL during frontend work for HMR.
|
||||
flowchart TD
|
||||
A[Home — timeline + movements] -->|scroll / drag / zoom| A
|
||||
A -->|click portrait| B[Artist bio]
|
||||
B -->|Enter Gallery| C[3D hall]
|
||||
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.
|
||||
- **3D gallery images** use locally cached files only (`galleryImageUrl`); slow remote fetches would break realtime rendering.
|
||||
- **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
|
||||
|
||||
@@ -34,6 +34,8 @@ File names are sanitised `{Artist}_{Title}.{ext}`. The image service can redisco
|
||||
- Downloads painting images into `paintings/`.
|
||||
3. Writes **painting_influences** edges from curated scholarship references.
|
||||
|
||||
Those influence edges also power **3D hall navigation**: predecessors and successors at each artist’s exit doorway are computed from this table (see `GET /api/artists/:id/navigation` in [API.md](API.md)).
|
||||
|
||||
Artists are grouped by movement and century; the seed list targets at most ~100 artists per century.
|
||||
|
||||
## On-demand image resolution
|
||||
|
||||
@@ -99,5 +99,6 @@ After clone: copy `.env.example` → `.env`, install dependencies, run `npm run
|
||||
| Empty timeline | DB not seeded | `npm run seed` |
|
||||
| 500 on all `/api/*` | Wrong `.env` or Postgres down | Check connection, logs |
|
||||
| Black frames in 3D gallery | No local image for painting | `POST …/preload-images` or `npm run fetch-images` |
|
||||
| Empty exit navigation lists | No `painting_influences` edges for artist | `npm run update-influences` or extend seed data |
|
||||
| Default Vite page instead of gallery | `client/dist` missing or stale | `cd client && npm run build` |
|
||||
| Permission denied creating tables | `gallery` user lacks CREATE | Run admin grants, then migrate |
|
||||
Reference in new issue
Block a user