巧用漸變實現高階感拉滿的背景光動畫

chokcoco發表於2021-11-24

背景

在上一篇 巧用濾鏡實現高階感拉滿的文字快閃切換效果 中,我們提到了一種非常有意思的之前蘋果展示文字的動畫效果。

本文,會帶來另外一個有意思的效果,巧用漸變實現高階感拉滿的背景光動畫。此效果運用在蘋果官網 iPhone 13 Pro 的介紹頁中:

實現

這個效果想利用 CSS 完全複製是比較困難的。CSS 模擬出來的光效陰影相對會 Low 一點,只能說是儘量還原。

其實每組光都基本是一樣的,所以我們只需要實現其中一組,就幾乎能實現了整個效果。

觀察這個效果:

它的核心其實就是角向漸變 -- conic-gradient(),利用角向漸變,我們可以大致實現這樣一個效果:

<div></div>
div {
    width: 1000px;
    height: 600px;
    background:
        conic-gradient(
            from -45deg at 400px 300px,
            hsla(170deg, 100%, 70%, .7),
            transparent 50%,
            transparent),
            linear-gradient(-45deg, #060d5e, #002268);
}

看看效果:

有點那意思了。當然,仔細觀察,漸變的顏色並非是由一種顏色到透明就結束了,而是顏色 A -- 透明 -- 顏色 B,這樣,光源的另一半並非就不會那麼生硬,改造後的 CSS 程式碼:

div {
    width: 1000px;
    height: 600px;
    background:
        conic-gradient(
            from -45deg at 400px 300px,
            hsla(170deg, 100%, 70%, .7),
            transparent 50%,
            hsla(219deg, 90%, 80%, .5) 100%),
            linear-gradient(-45deg, #060d5e, #002268);
}

我們在角向漸變的最後多加了一種顏色,得到觀感更好的一種效果:

emm,到這裡,我們會發現,僅僅是角向漸變 conic-gradient() 是不夠的,它無法模擬出光源陰影的效果,所以必須再借助其他屬性實現光源陰影的效果。

這裡,我們會很自然的想到 box-shadow。這裡有個技巧,利用多重 box-shadow, 實現 Neon 燈的效果。

我們再加個 div,通過它實現光源陰影:

<div class="shadow"></div>
.shadow {
    width: 200px;
    height: 200px;
    background: #fff;
    box-shadow: 
        0px 0 .5px hsla(170deg, 95%, 80%, 1),
        0px 0 1px hsla(170deg, 91%, 80%, .95),
        0px 0 2px hsla(171deg, 91%, 80%, .95),
        0px 0 3px hsla(171deg, 91%, 80%, .95),
        0px 0 4px hsla(171deg, 91%, 82%, .9),
        0px 0 5px hsla(172deg, 91%, 82%, .9),
        0px 0 10px hsla(173deg, 91%, 84%, .9),
        0px 0 20px hsla(174deg, 91%, 86%, .85),
        0px 0 40px hsla(175deg, 91%, 86%, .85),
        0px 0 60px hsla(175deg, 91%, 86%, .85);
}

OK,光是有了,但問題是我們只需要一側的光,怎麼辦呢?裁剪的方式很多,這裡,我介紹一種利用 clip-path 進行對元素任意空間進行裁切的方法:

.shadow {
    width: 200px;
    height: 200px;
    background: #fff;
    box-shadow: .....;
    clip-path: polygon(-100% 100%, 200% 100%, 200% 500%, -100% 500%);
}

原理是這樣的:

這樣,我們就得到了一側的光:

這裡,其實 CSS 也是有辦法實現單側陰影的(你所不知道的 CSS 陰影技巧與細節),但是實際效果並不好,最終採取了上述的方案。

接下來,就是利用定位、旋轉等方式,將上述單側光和角向漸變重疊起來,我們就可以得到這樣的效果:

image

這會,已經挺像了。接下來要做的就是讓整個圖案,動起來。這裡技巧也挺多的,核心還是利用了 CSS @Property,實現了角向漸變的動畫,並且讓光動畫和角向漸變重疊起來。

我們需要利用 CSS @Property 對程式碼漸變進行改造,核心程式碼如下:

<div class="wrap">
    <div class="shadow"></div>
</div>
@property --xPoint {
  syntax: '<length>';
  inherits: false;
  initial-value: 400px;
}
@property --yPoint {
  syntax: '<length>';
  inherits: false;
  initial-value: 300px;
}

.wrap {
    position: relative;
    margin: auto;
    width: 1000px;
    height: 600px;
    background:
        conic-gradient(
            from -45deg at var(--xPoint) var(--yPoint),
            hsla(170deg, 100%, 70%, .7),
            transparent 50%,
            hsla(219deg, 90%, 80%, .5) 100%),
            linear-gradient(-45deg, #060d5e, #002268);
    animation: pointMove 2.5s infinite alternate linear;
}

.shadow {
    position: absolute;
    top: -300px;
    left: -330px;
    width: 430px;
    height: 300px;
    background: #fff;
    transform-origin: 100% 100%;
    transform: rotate(225deg);
    clip-path: polygon(-100% 100%, 200% 100%, 200% 500%, -100% 500%);
    box-shadow: ... 此處省略大量陰影程式碼;
    animation: scale 2.5s infinite alternate linear;
}
 
@keyframes scale {
    50%,
    100% {
        transform: rotate(225deg) scale(0);
    }
}

@keyframes pointMove {
    100% {
        --xPoint: 100px;
        --yPoint: 0;
    }
}

這樣,我們就實現了完整的一處光的動畫:

我們重新梳理一下,實現這樣一個動畫的步驟:

  1. 利用角向漸變 conic-gradient 搭出基本框架,並且,這裡也利用了多重漸變,角向漸變的背後是深色背景色;
  2. 利用多重 box-shadow 實現光及陰影的效果(又稱為 Neon 效果)
  3. 利用 clip-path 對元素進行任意區域的裁剪
  4. 利用 CSS @Property 實現漸變的動畫效果

剩下的工作,就是重複上述的步驟,補充其他漸變和光源,除錯動畫,最終,我們就可以得到這樣一個簡單的模擬效果:

由於原效果是 .mp4,無法拿到其中的準確顏色,無法拿到陰影的引數,其中顏色是直接用的色板取色,陰影則比較隨意的模擬了下,如果有原始檔,準確引數,可以模擬的更逼真。

完整的程式碼你可以戳這裡:CodePen -- iPhone 13 Pro Gradient

最後

本文更多的是圖一樂呵,實際中製作上述效果肯定是有更為優雅的解法,並且利用 CSS 模擬的話,也應該有更好的方法,這裡我僅僅是拋磚引玉,過程中的 1、2、3、4 技巧本身有一些還是值得借鑑學習的。

好了,本文到此結束,希望本文對你有所幫助 :)

想 Get 到最有意思的 CSS 資訊,千萬不要錯過我的公眾號 -- iCSS前端趣聞 ?

更多精彩 CSS 技術文章彙總在我的 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏。

如果還有什麼疑問或者建議,可以多多交流,原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。

相關文章