-
Notifications
You must be signed in to change notification settings - Fork 18
Comparing changes
Open a pull request
base repository: LayoutitStudio/polycss
base: main
head repository: LayoutitStudio/polycss
compare: feat/poly-iframe
- 17 commits
- 24 files changed
- 1 contributor
Commits on Jun 4, 2026
-
feat(iframe): <poly-iframe> element + /television demo
Adds a new public element across all three renderers for placing live iframes in 3D space, plus a five-TV demo page. - packages/polycss: PolyIframeElement (vanilla custom element). Mounts an iframe wrapper inside the parent <poly-scene>'s .polycss-scene so the CSS camera transform composes naturally with surrounding meshes. Same position/rotation/scale conventions as <poly-mesh> post-parity (world units, world-axis order, rotation conjugation rotateY(-rx) rotateX(-ry) rotateZ(-rz)). Width/height in world units; iframe centred at the wrapper's local origin so rotation/scale pivot at the visible centre. - packages/react: <PolyIframe> mirror with the same props. - packages/vue: <PolyIframe> mirror with the same props. - 14/8/7 tests added per package; transform math + attribute forwarding pinned. AGENTS.md updated with the new element + naming entry. Bug fixes shipped alongside: - PolyPerspectiveCameraElement / PolyOrthographicCameraElement runtime attribute updates now mutate the camera handle in place and re-apply the scene transform. Before, the elements either recreated the handle (orphaning the scene's pointer) or updated but never called applyCamera, so rot-x/rot-y/zoom changes were ignored at runtime. - DocsHeader hides the floating search dock on /television (matches /gallery, /builder, /wordart). /television demo: - Vertical-rail TV picker (5 sets, hand-drawn SVG art per tile). ?tv=id query param + popstate sync so individual TVs are linkable. - Per-TV polygon indices identify which face(s) are the screen; the page derives the iframe's world-unit position, rotation, width, and height from those polygons' vertices at load time (area-weighted normal, bbox in the in-plane right/up basis, small lift along the normal so the iframe doesn't z-fight with the screen polygon itself). Per-TV rotY + zoom remain hand-tuned because GLB authoring orientations differ. - Retro Stack uses multiple screen entries — one <poly-iframe> per CRT is mounted dynamically and each is placed independently.
Configuration menu - View commit details
-
Copy full SHA for 42d17b1 - Browse repository at this point
Copy the full SHA 42d17b1View commit details -
feat(tv): rename /television → /tv, add header nav + floor + lighting
- Rename /television route + public assets to /tv (shorter, link to it from the docs header next to WordArt). - Query param renamed to ?model=<id> (was ?tv=<id> — reads better alongside /tv). - Brighter scene lighting (directional 4.5→6.5, ambient 0.55→0.9) plus a ground <poly-plane> below each TV with cast-shadow on the mesh, so the bottom of every TV sits visibly on the floor. Element changes to support the floor: - PolyShapeElement now forwards `cast-shadow` / `receive-shadow` to scene.add (mirrors <poly-mesh>) and `exclude-from-auto-center` so ground planes don't skew the scene's auto-center calculation. - PolyShapeElement gains an attributeChangedCallback so transform attrs (position/scale/rotation/shadow) propagate after mount — the floor is re-positioned per TV from the script side once the mesh has loaded. - PolyPlaneElement: new `offset` attribute, defaulting to 0 so the plane is centered at the element's local origin. The underlying planePolygons helper defaulted to size*2 because it was authored as a transform-control drag handle. Camera-element runtime fix: - PolyPerspectiveCameraElement / PolyOrthographicCameraElement attributeChangedCallback now correctly locates the scene as a descendant (`this.querySelector('poly-scene')`) rather than an ancestor. The previous walk-up version always found null and applyCamera was never called, so runtime rot-x/rot-y/zoom changes were no-ops in vanilla. Tuning: - TV mesh gets `auto-center` so its bbox center IS mesh-local (0,0,0). - Floor's per-preset Z is derived from the mesh's minZ on load. - Per-TV cam.rotY/zoom dialed in by hand for each set (pixel TV at rotY 245 / zoom 10 for a 3/4 view that doesn't crop).Configuration menu - View commit details
-
Copy full SHA for 9fee5e8 - Browse repository at this point
Copy the full SHA 9fee5e8View commit details -
tv: add polygon 216 to retro stack's first screen + TODO for shadows
- Retro stack screen 1: append poly 216 to the polyIndices array (user identified it as part of that CRT's bezel strip; was missing). - Floor shadow attempt: receiver-shadow on the floor + scene shadow config wired up cleanly, but the projected shadow SVG lands at wrong scene coords for our auto-centered TV + excludeFromAutoCenter floor combination. Vanilla dropped the legacy ground-shadow fallback for three.js parity, so a caster with no receiver draws nothing. Leaving the floor as a non-receiver for now with a TODO; lighting + floor geometry still ship.
Configuration menu - View commit details
-
Copy full SHA for 2fe3110 - Browse repository at this point
Copy the full SHA 2fe3110View commit details -
fix(tv): bump shadow.lift to 1 world unit so TV shadows clear the floor
The receiver-shadow SVG sits at the floor plane plus `shadow.lift` (default 0.05 world units = 2.5 CSS px). On a big 400-world-unit floor viewed at a normal-angle camera (rotX 70), that razor-thin gap z-fought with the floor itself and the shadow only showed from straight overhead. A 1 world unit (50 CSS px) lift puts the shadow clearly in front at every angle the camera reaches.
Configuration menu - View commit details
-
Copy full SHA for 3b32528 - Browse repository at this point
Copy the full SHA 3b32528View commit details -
fix(tv): drop poly 211 from retro stack's first screen
The first CRT's actual screen polygons are 212–216 — 211 is an adjacent bezel face the iframe-placement code was averaging into the plane, shifting the iframe off the screen. Restricting to 212–216 lands the iframe on the visible glass.
Configuration menu - View commit details
-
Copy full SHA for 5f51765 - Browse repository at this point
Copy the full SHA 5f51765View commit details -
tv: per-screen
liftoverride; recess retro-stack iframes into bezelsplacementFromPolygons now takes an optional liftOverride; the TvScreen config exposes it as `lift`. The retro stack's CRT screens already model the front glass surface, so a small negative lift (−0.6 world units) seats the iframe inside the bezel instead of in front of it. The default lift formula (0.2 + 0.01 * max(w,h)) still applies for every other TV — those polygons mark the screen plane itself, so the iframe sitting slightly in front of them reads as the picture surface.
Configuration menu - View commit details
-
Copy full SHA for 5401d64 - Browse repository at this point
Copy the full SHA 5401d64View commit details -
Configuration menu - View commit details
-
Copy full SHA for 7d85e2d - Browse repository at this point
Copy the full SHA 7d85e2dView commit details -
Configuration menu - View commit details
-
Copy full SHA for c62d2a5 - Browse repository at this point
Copy the full SHA c62d2a5View commit details -
Configuration menu - View commit details
-
Copy full SHA for b5e070a - Browse repository at this point
Copy the full SHA b5e070aView commit details -
Configuration menu - View commit details
-
Copy full SHA for 9ade7e3 - Browse repository at this point
Copy the full SHA 9ade7e3View commit details -
Configuration menu - View commit details
-
Copy full SHA for 4477e0a - Browse repository at this point
Copy the full SHA 4477e0aView commit details -
tv: re-enable receive-shadow on the TV mesh + bump shadow opacity
The 'floating quad' I attributed to receive-shadow earlier turned out to be the monitor.glb's back panel authored at an offset position — present even without receive-shadow. Self-shadows on textured receivers are computed correctly but the texturedReceiver code reduces opacity to mimic three.js's 'darken to ambient-only' (`effOp = opacity * (1 - (ambient/total)^(1/2.4))`). With our bright light (dir 6.5, ambient 0.9) that pushed shadow alpha to ~0.32, which read as nearly-invisible 'white-ish' on textured TVs. Bumping the input opacity to 0.95 lands the effective alpha at ~0.55 and the self-shadows now read as actually dark.
Configuration menu - View commit details
-
Copy full SHA for e928b19 - Browse repository at this point
Copy the full SHA e928b19View commit details -
tv: shadow tweaks — lower lift back to 0.1, drop ambient so shadows r…
…ead dark - Lift 1 → 0.1 world units. The bigger value was detaching shadows visibly from their receivers; 0.1 (5 CSS px) still clears z-fighting but reads as flush with the floor / bezel. - Ambient intensity 0.9 → 0.4. The texture-receiver code caps shadow alpha at `opacity * (1 - (ambient/total)^(1/2.4))` to mimic three.js's 'darken to ambient-only' lighting model. With ambient=0.9 the cap pushed effective shadow alpha to ~0.32 — visibly faint / 'white-ish' on the TV's own faces. Lower ambient = darker possible shadows; 0.4 hits the polycss default and lets self-shadows read as properly dark.
Configuration menu - View commit details
-
Copy full SHA for 59d94d6 - Browse repository at this point
Copy the full SHA 59d94d6View commit details -
Configuration menu - View commit details
-
Copy full SHA for 59155ca - Browse repository at this point
Copy the full SHA 59155caView commit details -
tv: Orbit/FPV camera-mode pill + wider zoom range
- Bottom-centre toggle switches between <poly-orbit-controls> and <poly-first-person-controls>. FPV mounts with WASD/jump/look and a hint label appears on the right side of the pill while active. - Orbit zoom range widened to [1, 200] so users can zoom out far past each TV's default zoom.
Configuration menu - View commit details
-
Copy full SHA for 9db0e88 - Browse repository at this point
Copy the full SHA 9db0e88View commit details -
tv: disable self-shadow + match gallery's FPV camera feel
- Drop receive-shadow from the TV mesh: the texture-receiver darkening reads as 'white-ish' (capped at ambient brightness) and visible self-shadows weren't worth the cost. - FPV mode now matches the gallery's defaults: move-speed 30, jump-velocity 25, gravity 60, eye-height 6, look-sensitivity 0.15. Also switches camera perspective to 2000 while FPV is active (the same FPV_PERSPECTIVE the gallery and builder use) for a wider FOV; restores to 32000 when going back to Orbit.
Configuration menu - View commit details
-
Copy full SHA for 9345369 - Browse repository at this point
Copy the full SHA 9345369View commit details -
tv: FPV spawns BEHIND the TV looking at it (matches gallery's useFpvS…
…pawn) Entering FPV used to drop the camera at scene origin (where the TV sits, since the scene is auto-centered) — so the player was INSIDE the TV with a face full of bezel. Now matching gallery's spawn behaviour: - Save + drop scene's auto-center attribute on entry, restore on exit. - Compute TV bbox from the loaded mesh handle, derive a spawn target one mesh-span behind the TV along the current rotY look direction, set it on the camera so the controls' initializeOriginFromTarget uses that as the seed. - Remove target on exit so orbit returns to its scene-origin pivot.
Configuration menu - View commit details
-
Copy full SHA for 82eca8b - Browse repository at this point
Copy the full SHA 82eca8bView commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff main...feat/poly-iframe