iT邦幫忙

2026 iThome 鐵人賽

DAY 25
0
Software Development

從零打造網頁簡報編輯器系列 第 25 篇

Day 25|讓簡報支援全螢幕、黑畫面與轉場

  • 分享至 

  • xImage
  •  

系列:一張投影片背後的工程:從零打造網頁簡報編輯器

對應程式:2026-10-04 工作目錄,package.json 版本 0.20.0,包含本篇的減少動態效果修正;這是工作目錄版本,尚未建立同名 Git tag。

到 Day 24,我們已經把基本編輯、復原、保存與備份串起來。前面的文章主要以 v0.4.0 拆解這些基礎;連載期間,程式也持續加入後續功能,因此從這篇開始,會接上目前 0.20.0 工作目錄累積的成果。

最後六篇會先處理簡報的播放與交付,再改善編排效率,最後量測效能並整理作品。今天先從實際分享開始:完成一份研究分享簡報後,講者能不能收起編輯工具、連續換頁,並在討論時暫時讓觀眾把注意力移回自己?

我用三頁示範回答這個問題:第一頁介紹研究、第二頁整理交付方式、第三頁放補充資料並標記略過。播放時只出現前兩頁;第二頁設定淡入,並能用按鍵切換全螢幕與黑畫面。

https://ithelp.ithome.com.tw/upload/images/20261005/20182759N1ZSndUqav.png

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 不會跟著做進場動畫。

一個實測才發現的 CSS 問題

這次檢查時,我模擬系統的「減少動態效果」,預期動畫停用,讀到的 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,檢查交付出去的內容。


上一篇
Day 24|讓含圖片的備份可以完整往返
系列文
從零打造網頁簡報編輯器 共 25 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言