feat(chemistry): Learn → Chemistry periodic-table landing (three.js CSS3D) — Phase 1 #738

Closed
opened 2026-07-20 17:32:37 +00:00 by spikerj · 2 comments
Owner

Why

Kick off a new Chemistry learning section, visual-first (a three.js CSS3D periodic table) rather than text-first — the analog of our C# programming lessons, where content reveals only as the learner earns the understanding to see it. Basis: the three.js example https://threejs.org/examples/css3d_periodictable.html.

This ticket tracks Phase 1 (shipped by the linked PR) and records the phased roadmap.

Phase 1 (this PR) — the faithful landing

Learn → Chemistry lands on the CSS3D periodic table rendering exactly like the demo: all 118 elements, the four layouts (table / sphere / helix / grid), TWEEN morphing, trackball orbit + zoom. No click handling, modal, or gating yet.

Decomposition into our Angular v22 ecosystem:

  • App-local under projects/spikersoft/src/app/_components/learning/chemistry/ (matches the other three.js scenes and Learning tiles — no new Nx lib).
  • Element data ported verbatim (periodic-table.data.ts); layout math extracted to a pure, unit-tested function (periodic-table.layouts.ts).
  • PeriodicTableComponent — dynamic three + three/addons/{renderers/CSS3DRenderer,controls/TrackballControls,libs/tween.module} imports, ViewEncapsulation.None scoped under .chemistry-periodic-table (tiles are created imperatively), zoneless rAF loop, disciplined teardown.
  • ChemistryLandingPageComponent@defer (on viewport) route wrapper (epic #722 E6), so the three.js payload splits out of the route chunk.
  • Wiring: route in routes.ts (public) + e2e/support/route-manifest.ts; menu entry in desktop #learnMenu and the mobile drawer; en/es i18n.

Acceptance criteria (Phase 1)

  • Learn → Chemistry (desktop + mobile) routes to /chemistry
  • CSS3D periodic table renders like the demo; all four layouts + orbit/zoom work
  • three.js absent from the initial bundle — loads only via the deferred scene chunk
  • unit tests, nx build spikersoft, lint/prettier/stylelint, i18n scan all green

Roadmap (later PRs, designed but not built here)

  • Phase 2 — click → in-scene detail. CSS3D tiles are real DOM, so clicks are plain DOM listeners (no raycasting); disambiguate click vs TrackballControls drag. Clicked tile TWEEN-zooms to center and expands into a detail card; rest of the table dims.
  • Phase 3 — progressive unlock. Author chemistry as backend Kind.Tutorial lesson strategies with real Prerequisites (Mongo-hydrated, reuse /api/Lessons/progress + ProgressSyncService); reuse the client-side isUnlocked = prerequisites.every(p => completedSet.has(p)) derivation. Not-yet-understood elements render as an obscured placeholder tile ("?" silhouette, slot kept, identity hidden) until unlocked. Note: today's unlock derivation is client-side only for authed users — hard server-side element locking, if wanted, is net-new work modeled on the anonymous-horizon 423 path.
## Why Kick off a new **Chemistry** learning section, visual-first (a three.js CSS3D periodic table) rather than text-first — the analog of our C# programming lessons, where content reveals only as the learner earns the understanding to see it. Basis: the three.js example https://threejs.org/examples/css3d_periodictable.html. This ticket tracks **Phase 1** (shipped by the linked PR) and records the phased roadmap. ## Phase 1 (this PR) — the faithful landing `Learn → Chemistry` lands on the CSS3D periodic table rendering exactly like the demo: all 118 elements, the four layouts (table / sphere / helix / grid), TWEEN morphing, trackball orbit + zoom. No click handling, modal, or gating yet. Decomposition into our Angular v22 ecosystem: - App-local under `projects/spikersoft/src/app/_components/learning/chemistry/` (matches the other three.js scenes and Learning tiles — no new Nx lib). - Element data ported verbatim (`periodic-table.data.ts`); layout math extracted to a pure, unit-tested function (`periodic-table.layouts.ts`). - `PeriodicTableComponent` — dynamic `three` + `three/addons/{renderers/CSS3DRenderer,controls/TrackballControls,libs/tween.module}` imports, `ViewEncapsulation.None` scoped under `.chemistry-periodic-table` (tiles are created imperatively), zoneless rAF loop, disciplined teardown. - `ChemistryLandingPageComponent` — `@defer (on viewport)` route wrapper (epic #722 E6), so the three.js payload splits out of the route chunk. - Wiring: route in `routes.ts` (public) + `e2e/support/route-manifest.ts`; menu entry in desktop `#learnMenu` and the mobile drawer; en/es i18n. ### Acceptance criteria (Phase 1) - [x] `Learn → Chemistry` (desktop + mobile) routes to `/chemistry` - [x] CSS3D periodic table renders like the demo; all four layouts + orbit/zoom work - [x] three.js absent from the initial bundle — loads only via the deferred scene chunk - [x] unit tests, `nx build spikersoft`, lint/prettier/stylelint, i18n scan all green ## Roadmap (later PRs, designed but not built here) - **Phase 2 — click → in-scene detail.** CSS3D tiles are real DOM, so clicks are plain DOM listeners (no raycasting); disambiguate click vs TrackballControls drag. Clicked tile TWEEN-zooms to center and expands into a detail card; rest of the table dims. - **Phase 3 — progressive unlock.** Author chemistry as backend `Kind.Tutorial` lesson strategies with real `Prerequisites` (Mongo-hydrated, reuse `/api/Lessons/progress` + `ProgressSyncService`); reuse the client-side `isUnlocked = prerequisites.every(p => completedSet.has(p))` derivation. Not-yet-understood elements render as an **obscured placeholder tile** ("?" silhouette, slot kept, identity hidden) until unlocked. Note: today's unlock derivation is client-side only for authed users — hard server-side element locking, if wanted, is net-new work modeled on the anonymous-horizon 423 path.
Author
Owner

PR open: spikerj/spikersoft-angular#467 (branch feat/chemistry-periodic-table, base master). Phase 1 — the periodic-table landing. Will comment the merge SHA and close this ticket once it merges.

PR open: spikerj/spikersoft-angular#467 (branch `feat/chemistry-periodic-table`, base `master`). Phase 1 — the periodic-table landing. Will comment the merge SHA and close this ticket once it merges.
Author
Owner

Phase 1 merged to master via spikerj/spikersoft-angular#467 (feature commit 8d3ead4d, merge 9f2efa6b4fd5). The faithful CSS3D periodic-table landing is live. Closing — follow-up work (sizing polish, camera reset/axis views, in-scene element zoom, and Phase-3 unlock gating) will be tracked under its own tickets.

Phase 1 merged to `master` via spikerj/spikersoft-angular#467 (feature commit `8d3ead4d`, merge `9f2efa6b4fd5`). The faithful CSS3D periodic-table landing is live. Closing — follow-up work (sizing polish, camera reset/axis views, in-scene element zoom, and Phase-3 unlock gating) will be tracked under its own tickets.
Sign in to join this conversation.