用CSS 給《狂飆》做了4種轉場

語言: CN / TW / HK

theme: channing-cyan

前言

最近《狂飆》大火,順便蹭個熱度,用CSS給狂飆做個轉場動畫。本文介紹了4種轉場過渡效果,分別是水平擦除轉場星型轉場時鐘轉場自定義圖形縮放轉場

相信你肯定大有收穫。

一個簡單的漸變蒙版

CSS 蒙版允許您控制元素的顯示情況。遮罩可以是圖像或漸變。當蒙版應用於元素時,它充當一種映射。
遮罩可以使得元素部分被遮蓋,從而產生半透明的樣子。

下面的演示使用 CSS 遮罩將兩圖片交叉顯示,呈現出淡入淡出。

jcode

第一個場景是高啟強。第二個場景是 安欣,他直接位於第一個場景之上。在第二個場景中使用漸變蒙版使其左側透明,從而將第一個場景顯示出。

CSS中主要是定位和調整大小,以及設置場景圖像,但要注意 .scene-2 上的 -webkit-mask-image

``` .wrapper { width: min(1000px, 100%); }

.scenes { position: relative; aspect-ratio: 2.4 / 1; }

.scene-1, .scene-2 { position: absolute; inset: 0; background-size: cover; }

.scene-1 { background-image: url(scene-1.jpg); }

.scene-2 { background-image: url(scene-2.jpg); -webkit-mask-image: linear-gradient(to right, transparent 33%, #fff 67%); } ```

-webkit-mask-image 上設置遮罩linear-gradient() ,表示從左到右的

  • 前三分之一是完全透明的,所以這部分場景是不可見的
  • 中間的三分之一從透明變為不透明的白色,場景逐漸淡入
  • 最後三分之一是完全不透明的白色,導致這部分場景完全可見

透明像素隱藏不透明像素顯示。顏色甚至都不重要。任何顏色都可以。

另外,我使用的前綴為 -webkit-mask-image (所有主流瀏覽器均支持),但不使用 mask-image (目前僅 Firefox 和 Safari 可識別)。

.scene-2 { -webkit-mask-image: linear-gradient(to right, transparent 33%, #fff 67%); mask-image: linear-gradient(to right, transparent 33%, #fff 67%); }

水平擦除過渡轉場

第一個場景過渡效果,即水平淡入淡出。

jcode

基本的 HTML 和 CSS 設置與上次相同。再一次,遮罩是一個 linear-gradient() ,從中間從 transparent 漸變到 #fff

那麼淡入淡出是如何在場景中動畫化的呢?

下方的可視化器。遮罩被拉伸到比實際場景更寬,然後動畫水平滑動。

``` .scene-2 { background-image: url(scene-2.jpg); -webkit-mask-image: linear-gradient( to right, transparent 47.5%, #fff 52.5% ); -webkit-mask-size: 210%; -webkit-mask-position: left; }

/ 當.scenes 被聚焦或者移入的時候,在.scenes-2的這些樣式激活/ .scenes:is(:hover, :focus) .scene-2 { -webkit-mask-position: right; transition: -webkit-mask-position 2s linear; } ```

遮罩的大小為 -webkit-mask-size: 210% 為場景提供了 100% 的寬度,

最終形成:開始完全透明 + 10% 的淡入淡出 + 另一個完全不透明

為了顯示場景,我們將 -webkit-mask-position 的值設為 transition ,因此遮罩從 left 對齊變為 right 對齊。請注意, background-image 不會移動,只有遮罩會移動。

CSS 遮罩不僅遮罩了元素的背景,它還遮罩了整個元素及其中的所有內容

星形轉場

接下來是星形轉場,從中間淡出場景。注意,動畫依賴於 CSS properties and values API

jcode

這次我們使用 radial-gradient() 作為遮罩。我們還需要以下方式處理動畫。

定義 radial-gradient() 。然後我們可以對該自定義屬性進行動畫處理以對漸變進行動畫處理。

但在此之前,我們需要使用 @property 註冊自定義屬性。

js @property --radius { syntax: '<percentage>'; inherits: true; initial-value: -5%; }

--radius 的自定義屬性,它保存 percentage 值並且默認值為 -5% 。並使用簡單的關鍵幀動畫為 --radius 設置動畫。

@keyframes scene-transition { to { --radius: 105%; } }

.scene-2 的 CSS組合在一起。

``` .scene-2 { background-image: url(scene-2.jpg); z-index: -1; -webkit-mask-image: radial-gradient( circle, #fff calc(var(--radius) - 5%), transparent calc(var(--radius) + 5%) ); }

.scenes:is(:hover, :focus) .scene-2 { z-index: 1; animation: scene-transition 2s linear forwards; } ```

radial-gradient() 中的顏色停止位置也是如此。是 --radius 值的 -5%+5% ,創建出漸變淡入淡出。

淡入淡出是 --radius 的值從 -5% 變為 105% 的原因。我們在開始時額外多出的 5% 確保所有像素都隱藏,然後在最後多出 5% 以確保所有像素都可見

但是這個 API 在 Firefox 和 Safari 中不起作用。我們可以將 .scene-2 設置 z-index: -1 ,將其隱藏在第一個場景後面,然後改成 z-index: 1 以將其顯示在第一個場景之上。

時鐘轉場

jcode

我們使用 conic-gradient()angle 值設置動畫。

``` @property --angle { syntax: ''; inherits: true; initial-value: -10deg; }

@keyframes scene-transition { to { --angle: 370deg; } }

.scene-2 { background-image: url(scene-2.jpg); z-index: -1; -webkit-mask-image: conic-gradient( #fff 0deg, #fff calc(var(--angle) - 10deg), transparent calc(var(--angle) + 10deg), transparent 360deg ), conic-gradient( transparent 340deg, #fff 360deg ); }

.scenes:is(:hover, :focus) .scene-2 { z-index: 1; animation: scene-transition 2s linear forwards; } ```

我們在 -webkit-mask-image 中使用了兩個漸變。第一個 conic-gradient() 被動畫化以創建時鐘擦除效果,但它在其起點( 0deg 處)。漸變結合在一起為場景創建蒙版。

自定義圖形縮放轉場

jcode

.scene-2 的 CSS

``` @keyframes scene-transition { 25% { filter: brightness(100%); } 100% { filter: brightness(100%); -webkit-mask-size: 1800%; } }

.scene-2 { background-image: url(scene-2.jpg); filter: brightness(0%); -webkit-mask-image: url(jedi-crest.svg); -webkit-mask-size: 10%; -webkit-mask-position: center; -webkit-mask-repeat: no-repeat; }

.scenes:is(:hover, :focus) .scene-2 { animation: scene-transition 4s cubic-bezier(1, 0, 1, 1) forwards; } ```

這次沒有漸變。相反, -webkit-mask-image 是一個 SVG,將 .scene-2 遮罩。遮罩位於場景的 center 中,大小為 10% 。添加 filter: brightness(0%) 會消除所有亮度,導致 SVG 完全變黑。

動畫使用 cubic-bezier() 曲線,開始時非常慢,然後變得非常快。

-webkit-mask-size10%1800% 動畫化,使得絕地 SVG 中間的狹窄部分變得足夠大以覆蓋整個場景。

filter: brightness()0%100% 動畫,場景從黑色淡化回正常。這部分動畫設置為在 -webkit-mask-size 完成生長之前在 25% 時間標記處結束。

全文完

謝謝!

開啟掘金成長之旅!這是我參與「掘金日新計劃 · 2 月更文挑戰」的第 12 天

點擊查看活動詳情