From b64ce0f8320408e74bf535f25f6c7140e94cf927 Mon Sep 17 00:00:00 2001 From: lewis Date: Fri, 17 Apr 2026 23:27:05 +0800 Subject: [PATCH] perf(presenter): smooth navigation via postMessage (no reload, no flicker) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: Switching slides reset iframe.src each time, causing visible flicker (white flash → load → render) on every navigation. Solution: load each preview iframe ONCE, then use postMessage for all subsequent slide changes. The iframe stays mounted; only .is-active class toggles between slides inside it. Changes: - runtime.js preview mode: now exposes a showSlide() function and listens for window.message events of type 'preview-goto'. Also posts 'preview-ready' to parent on init so the presenter window knows when each iframe is loaded. - presenter window: tracks iframeReady state per iframe; first frame renders via iframe.src = ?preview=N (one-time), all subsequent navigation goes through postPreviewGoto() → postMessage. Notes, meta, and timer update directly without touching iframes. - Init no longer calls update(idx) which used to reset iframe.src; instead inits notes/meta/count once and lets the load→ready flow populate previews. Docs synced to match new architecture: - SKILL.md: describes 4 magnetic cards, draggable/resizable, with the iframe ?preview=N pattern explained for AI consumers - references/presenter-mode.md: updated ASCII diagram to show 4 cards, removed old 58%/35% layout description, added explanation for why previews are pixel-perfect (iframe loads same HTML) and why navigation is flicker-free (postMessage, not reload) - presenter-mode-reveal README: updated 4-card description --- SKILL.md | 17 +++- assets/runtime.js | 90 ++++++++++++++----- references/presenter-mode.md | 51 +++++++---- .../presenter-mode-reveal/README.md | 19 +++- 4 files changed, 132 insertions(+), 45 deletions(-) diff --git a/SKILL.md b/SKILL.md index fd9b211..0250b9a 100644 --- a/SKILL.md +++ b/SKILL.md @@ -24,7 +24,7 @@ One command, no build. Pure static HTML/CSS/JS with only CDN webfonts. - **31 layouts** (`templates/single-page/*.html`) with realistic demo data - **27 CSS animations** (`assets/animations/animations.css`) via `data-anim` - **20 canvas FX animations** (`assets/animations/fx/*.js`) via `data-fx` — particle-burst, confetti-cannon, firework, starfield, matrix-rain, knowledge-graph (force-directed), neural-net (pulses), constellation, orbit-ring, galaxy-swirl, word-cascade, letter-explode, chain-react, magnetic-field, data-stream, gradient-blob, sparkle-trail, shockwave, typewriter-multi, counter-explosion -- **Keyboard runtime** (`assets/runtime.js`) — arrows, T (theme), A (anim), F/O, **S (presenter view: current + next + large speaker script + timer)**, N (legacy notes drawer), R (reset timer) +- **Keyboard runtime** (`assets/runtime.js`) — arrows, T (theme), A (anim), F/O, **S (presenter mode: magnetic-card popup with CURRENT / NEXT / SCRIPT / TIMER cards)**, N (notes drawer), R (reset timer in presenter) - **FX runtime** (`assets/animations/fx-runtime.js`) — auto-inits `[data-fx]` on slide enter, cleans up on leave - **Showcase decks** for themes / layouts / animations / full-decks gallery - **Headless Chrome render script** for PNG export @@ -43,7 +43,17 @@ See [references/presenter-mode.md](references/presenter-mode.md) for the full au 2. **每页 150–300 字** — 2–3 分钟/页的节奏 3. **用口语,不用书面语** — "因此"→"所以","该方案"→"这个方案" -All full-deck templates support the S key presenter view (it's built into `runtime.js`). **S opens a separate popup window** — the original page stays as the audience view, and the popup shows current/next slide (CSS scale at 1920×1080 design resolution, pixel-perfect) + large speaker script + timer. The two windows sync navigation via BroadcastChannel. +All full-deck templates support the S key presenter mode (it's built into `runtime.js`). **S opens a new popup window with 4 magnetic cards**: +- 🔵 **CURRENT** — pixel-perfect iframe preview of the current slide +- 🟣 **NEXT** — pixel-perfect iframe preview of the next slide +- 🟠 **SPEAKER SCRIPT** — large-font 逐字稿 (scrollable) +- 🟢 **TIMER** — elapsed time + slide counter + prev/next/reset buttons + +Each card is **draggable by its header** and **resizable by the bottom-right corner handle**. Card positions/sizes persist to `localStorage` per deck. A "Reset layout" button restores the default arrangement. + +**Why the previews are pixel-perfect**: each preview is an `