- JavaScript 84.8%
- CSS 10.8%
- Python 2.9%
- Dockerfile 0.8%
- Shell 0.5%
- Other 0.2%
| .idea | ||
| backend | ||
| docker | ||
| docs | ||
| frontend | ||
| scripts | ||
| .gitignore | ||
| docker-compose.yml | ||
| LICENSE | ||
| README.md | ||
Art Gallery
Bilingual art gallery featuring a grid view, immersive 3D and AR gallery, and an artist spotlight that renders markdown bios.
Screenshots
Configure Your Own Dataset
Content is split between two directories:
frontend/public/<dataset>holds images, favicons, and any other static assets that should be served as-is.frontend/config/<dataset>contains JSON and Markdown that drive the gallery UI.
The Vite dev server (npm run dev) loads test, while production builds (npm run build) inline everything from deploy. Copy the bundled sample and then edit it:
- Bash:
cp -r frontend/public/test frontend/public/deployandcp -r frontend/config/test frontend/config/deploy - PowerShell:
Copy-Item -Recurse frontend/public/test frontend/public/deployandCopy-Item -Recurse frontend/config/test frontend/config/deploy
After editing the deploy variant, run npm run build and those resources will be embedded in the production bundle. You can keep tweaking test for fast dev reloads.
Directory Layout
frontend/
public/
deploy/
images/ # artwork photography, portraits, etc.
favicon.ico # optional dataset-specific icon
config/
deploy/
content/
en_profile.md
de_profile.md
data/
artist.json
artworks.json
gallery_map.json
materials.json
data/artworks.json
Array of artworks. Provide either a numeric id or a unique slug, plus localized strings and optional metadata.
[
{
"id": 1,
"slug": "aurora-dreams",
"title": { "en": "Aurora Dreams", "de": "Aurora Traeume" },
"description": {
"en": "An ethereal blend of cool tones inspired by polar lights.",
"de": "Eine luftige Mischung kuehler Toene, inspiriert vom Polarlicht."
},
"imageUrl": "/deploy/images/aurora.jpg",
"contactEmail": "studio@example.com",
"price": {
"en": "EUR 1,800",
"de": "1.800 EUR"
},
"materialId": 1,
"sold": false
}
]
Key fields:
title/description: locale-keyed objects (en,deby default).imageUrl: absolute path that points insidepublic/<dataset>/images.contactEmail: optional; adds the "Inquire" mail link.price: optional localized pricing block.materialId: optional link intomaterials.json.sold: optional boolean; sold pieces render in a dedicated section.
data/materials.json
Materials tune the 3D rendering of each artwork frame.
[
{
"id": 1,
"name": "Gallery Gloss",
"normalMap": "/assets/brush_strokes_normal_map.jpg",
"properties": {
"roughness": 0.3,
"metalness": 0.0,
"clearcoat": 0.7
}
}
]
Every material is referenced from artworks via materialId. All properties are optional; omit anything you want to fall back to defaults.
data/artist.json
Controls the artist spotlight. profileUrl accepts either a single Markdown file or a locale map.
{
"lastName": "Mustermann",
"imageUrl": "/deploy/images/artist.jpg",
"profileUrl": {
"en": "/config/deploy/content/en_profile.md",
"de": "/config/deploy/content/de_profile.md"
}
}
content/*.md
Markdown files are rendered with react-markdown. Headings, lists, emphasis, and links are supported.
data/gallery_map.json
Drives the immersive gallery layout.
tileSize,dimension,wallHeight,wallThickness: overall room scale.pillars: list of{ "tile": [x, y], "rotation": degrees }.lights: array of ceiling lights (currently type"point").spawn: starting position{ "tile": [x, y], "yawDegrees": number }.paintings: placements such as{ "tile": [x, y], "facing": "north", "artworkId": 1 }.sun: optional environment light.showLightIndicators: toggles debug helpers.
Use frontend/config/test/data/gallery_map.json as a template and adjust tiles to match your space.
Quick Checklist
- Add or replace images inside
frontend/public/<dataset>/images. - Update copy in JSON/Markdown under
frontend/config/<dataset>. - Keep locale keys consistent across JSON documents.
- Run
npm run buildto bakedeployassets into the production bundle.
Local Development
cd frontend && npm installnpm run devserves the app at http://localhost:5173 using thetestdataset.- Copy any assets you are editing into
frontend/public/test(and matching config) for instant reloads. - If you need to preview the production bundle locally, run
npm run build && npm run preview.
Telemetry Backend (optional)
The frontend only sends telemetry when VITE_ENABLE_TELEMETRY is true. Set the variable before starting Vite:
- PowerShell (session-scoped):
$env:VITE_ENABLE_TELEMETRY='true'; npm run dev - Bash:
VITE_ENABLE_TELEMETRY=true npm run dev
Steps to run the backend locally:
python -m venv .venv && .\.venv\Scripts\activatepip install -r backend/requirements.txt- Copy
backend/.example.envtobackend/.envand setTELEMETRY_PATHif you want to persist events. - Start the API on http://127.0.0.1:5100 with
python backend/app.py - (Recommended) Run the development proxy so
/api/*hits the backend while static assets come from Vite:python backend/dev_proxy.pyand open http://localhost:5000
When telemetry is disabled, events are dropped client-side and the UI hides the privacy notice banner.
Building & Deployment
npm run buildoutputs the static bundle tofrontend/dist. When telemetry is required in production, runVITE_ENABLE_TELEMETRY=true npm run build.- Docker helpers live in
scripts/:scripts/up-without-backend.shbuilds and serves the static site only.scripts/up-with-backend.shbuilds with telemetry enabled and starts Gunicorn behind Nginx.BACKEND_ENABLED=truecontrols whether/api/*is routed to Gunicorn.scripts/down.shstops whichever stack is running.
- Adjust
ART_GALLERY_WEB_PORT(default 8000) if the published port should change. - Provide your
deploydataset before building the container so the assets are available at runtime.
License
This project is GPLv3 Licensed.



