startViewTransition() API 介紹
這個 API 還在實驗性的階段,目前為止瀏覽器的支援率還不是很普及,我們可以從 Can I use 查到目前瀏覽器支援的比例
View Transitions API 他的方法就是會在兩個檔案之間建立一個過渡的動畫,當我們呼叫他的時候,他會在我們當前的頁面建立一個快照,就像是在你當前頁面截圖,接著就會開始對網頁上的內容進行變換,然後再一次的紀錄(但這次是變化過後的),再來他會將舊的頁面讓他有一個透明到 1~0 的變化,新的則是 0~1,使用戶能夠看到這段過渡的動畫效果。
在變化的過程網頁會停止渲染,我們也無法在網頁上進行任何互動或點擊效果
在變化的過程,會在瀏覽器中添加這些偽元素
已複製!::view-transition └─ ::view-transition-group(root) └─::view-transition-image-pair(root) ├─ ::view-transition-old(root) └─ ::view-transition-new(root)
::view-transition-old 就是舊的快照,::view-transition-new 則是新的被更改過後的樣子
他的動畫是完全可以由 CSS 來做控制的
已複製!::view-transition-new(root) { animation-duration: 5s; }
除了可以像這樣控制時間之外,也可以像是在寫一般 css 的動畫一樣,只要設定好我們想要的 keyframes 就能夠自己創建一個獨特的過渡動畫,只要記得 old 是舊的畫面,new 是新的畫面,就可以來寫上進入跟離開時的動畫效果了。
已複製!@keyframes slide-out { to { transform: translateY(-100%); } } ::view-transition-old(root) { animation: 300ms linear both slide-out; }
在不同元素上進行動畫
剛剛上述都是在 root 上去做變化,那如果只想要單一元素去使用這個 API 的話,只需要給他個名稱就可以了,可以使用 view-transition-name 這個屬性
已複製!element { view-transition-name: new-element; }
接著他就會以你這個命名的方式去生成新的偽元素,就能在不同的元素上去進行轉換了
view-transition-name 不能是重複的,如果多個元素同時具有相同的 view-transition-name,系統會略過轉場效果。
已複製!::view-transition └─ ::view-transition-group(root) └─::view-transition-image-pair(root) ├─ ::view-transition-old(root) └─ ::view-transition-new(root)
實際使用 startViewTransition()
先附上範例,這是一個單純移除掉資料的範例,正常清況下沒有特別去處理移除掉的元素,就只會單純消失而不會有一個過渡的變化,但我們加上了 startViewTransition() 這個 API 後,可以發現在刪除元素時,他不是直接消失的。
它的使用方法也很簡單,只需要加上 document.startViewTransition() 在你想要執行的地方就可以了。
已複製!const removeHandler = (id) => { document.startViewTransition(() => { setDummy(dummy.filter((item) => item.id !== id)); }); };
因為這項功能還在實驗中,有許多的瀏覽器還沒辦法使用個 API ,所以可以加上判斷這個瀏覽器是否可以使用再來執行
已複製!if (!document.startViewTransition) { setDummy(dummy.filter((item) => item.id !== id)); } //如果瀏覽器不支援這個 API 就直接執行
也可以運用這個來建立一些特別的變化,像是使用它來進行 dark mode 的切換動畫
已複製!const toggleRef = useRef(null); // 用 ref 來取得當前按鈕的位置 const { top, left } = toggleRef.current.getBoundingClientRect(); const right = window.innerWidth - left; const bottom = window.innerHeight - top; // 計算出按鈕到頁面最遠的半徑距離,也就是直角三角形最長的邊 const maxRadius = Math.hypot(Math.max(left, right), Math.max(top, bottom)); const circleAnimate = [ `circle(0px at ${left}px ${top}px)`, `circle(${maxRadius}px at ${left}px ${top}px)`, ]; document.documentElement.animate( { clipPath: circleAnimate, }, { duration: 1000, easing: "cubic-bezier(.04,.56,.8,.47)", pseudoElement: "::view-transition-new(root)", } );
大概是這樣去做計算從點擊位置到頁面的最遠處
使用 View Transitions API 流暢快速地轉換 | Web Platform | Chrome for Developers
Document: startViewTransition() method - Web APIs | MDN (mozilla.org)