系列:一張投影片背後的工程:從零打造網頁簡報編輯器
對應程式:2026-10-04 工作目錄,
package.json版本0.20.0,包含本篇的減少動態效果修正;這是工作目錄版本,尚未建立同名 Git tag。
到 Day 24,我們已經把基本編輯、復原、保存與備份串起來。前面的文章主要以 v0.4.0 拆解這些基礎;連載期間,程式也持續加入後續功能,因此從這篇開始,會接上目前 0.20.0 工作目錄累積的成果。
最後六篇會先處理簡報的播放與交付,再改善編排效率,最後量測效能並整理作品。今天先從實際分享開始:完成一份研究分享簡報後,講者能不能收起編輯工具、連續換頁,並在討論時暫時讓觀眾把注意力移回自己?
我用三頁示範回答這個問題:第一頁介紹研究、第二頁整理交付方式、第三頁放補充資料並標記略過。播放時只出現前兩頁;第二頁設定淡入,並能用按鍵切換全螢幕與黑畫面。

2026-10-04,以獨立的無介面 Edge 操作合成簡報後擷取。靜態截圖呈現播放介面,轉場與按鍵行為另由瀏覽器檢查。
| 操作 | 目前行為 |
|---|---|
| 方向鍵、Page Up/Page Down、空白鍵 | 切換上一頁或下一頁,停在有效頁面範圍內 |
| Home/End | 到第一張或最後一張可播放頁 |
| F 或全螢幕按鈕 | 請求進入或離開瀏覽器全螢幕 |
| B 或黑畫面按鈕 | 蓋住投影片,再按一次恢復;控制列仍可操作 |
| 結束播放 | 回到編輯器,保留目前瀏覽的頁面 |
Esc 由應用程式收到時也會結束播放;在瀏覽器全螢幕中,瀏覽器可能先用它離開全螢幕。因此保留可點擊的「結束播放」按鈕,不把離場方式全部壓在同一個鍵上。
播放沿用先前的投影片渲染器。這裡新增的重點是控制方式:黑畫面與全螢幕狀態只屬於這次播放,換頁也不會改寫文件或新增復原紀錄。
把容器放大到視窗,不等於真正進入瀏覽器全螢幕。PresentationMode 會在使用者操作時呼叫:
const request = document.fullscreenElement
? document.exitFullscreen()
: viewportRef.current?.requestFullscreen?.()
void request?.catch(() => undefined)
介面再監聽 fullscreenchange,以 document.fullscreenElement 是否為播放容器決定按鈕文字。這樣瀏覽器自行退出時,按鈕也能跟著更新。
全螢幕請求需要使用者觸發,也可能被瀏覽器政策拒絕。目前失敗時保留一般播放,沒有額外錯誤提示;這是之後能改善的使用回饋。MDN:requestFullscreen()
黑畫面只切換一層黑色遮罩,底下的投影片仍保留。它不是把背景改黑,也不會把這次播放狀態存進簡報。使用者仍可在黑畫面下換頁,恢復時顯示當時所在的頁面。
轉場則是投影片本身的設定。slide.transition 可選 none、fade 或 slide,播放容器會依目標頁加入相對應的 class:
<div
key={slide.id}
className={`presentation-mode__slide is-${slide.transition ?? 'none'}`}
>
{/* 投影片內容 */}
</div>
以投影片 ID 作為 key,換頁會建立新的動畫容器;淡入使用 280 毫秒,滑入使用 320 毫秒。這些 class 只放在播放器,所以縮圖和 PDF 不會跟著做進場動畫。
這次檢查時,我模擬系統的「減少動態效果」,預期動畫停用,讀到的 animationName 卻仍是 presentation-fade。
原本轉場使用兩個 class:
.presentation-mode__slide.is-fade {
animation: presentation-fade 280ms ease-out;
}
但媒體查詢裡只有 .presentation-mode__slide。即使寫在後面,較低的選擇器權重仍無法蓋過轉場。這次把停用規則改為相同權重:
@media (prefers-reduced-motion: reduce) {
.presentation-mode__slide.is-fade,
.presentation-mode__slide.is-slide {
animation: none;
}
}
媒體查詢決定規則是否適用,不會自動提高裡面選擇器的權重。在這份樣式中,同權重、同來源的後寫規則才能覆蓋前面的動畫宣告。MDN:CSS Specificity
修正後,瀏覽器檢查確認淡入與滑入的 animationName 都是 none。這也提醒我,確認 class 存在的 React 測試,還不足以驗證瀏覽器最後採用的 CSS。
建立三張標題不同的投影片,把第三張標記略過,第二張設定淡入。從第一張播放後,確認下一頁顯示 2 / 2;按 B 往返黑畫面,再用 F 和結束播放按鈕檢查進出流程。最後模擬減少動態效果,重新換頁,應不再出現動畫。
本次 scripts/article-evidence.mjs 已在獨立 Edge 設定檔驗證換頁、黑畫面、全螢幕請求與減少動態效果。它是自動化結果,不等同於人工測過每一種作業系統快捷鍵行為。講者備註仍只在編輯器保存與查看,目前沒有第二個講者視窗。
簡報現在可以拿來講;下一篇會把這份示範簡報真正輸出成兩頁 PDF,檢查交付出去的內容。