純CSS漸變繪製 Chrome 圖示

XboxYan發表於2023-05-08
歡迎關注我的公眾號:前端偵探

今天學習一下利用 CSS 漸變來繪製一個 Chrome 圖示,如下

image.png

如何僅使用漸變而不借助其他標籤呢?一起看看如何實現的吧

一、圖形拆解

乍一看好像沒法直接透過漸變寫出來,所以需要對圖形進行簡單的拆分。

中間的圓圈沒有什麼難度,主要是周圍的“扇形”,但是好像又不是完整的“扇形”,互相都有遮擋

經過一番思索,可以分解成這樣的幾個圖形,如下

image.png

這下每個部分是不是都可以用漸變寫出來了呢?

二、徑向漸變

假設 HTML 就一個標籤

<chrome></chrome>

中間的圓圈其實是藍色→白色→透明的漸變,然後加上橙色的底色,用程式碼實現就是

chrome{
  background: radial-gradient( closest-side circle, #477EE6 calc(100% - 10px), #fff 0 100%, transparent 0) center/90px no-repeat #F2C146;
}

注意,這裡使用了關鍵詞closest-side,表示最近的邊,好處是可以根據背景尺寸直接控制圓的大小,預設值是farthest-side,其他選項詳細如下

關鍵字描述
closest-side漸變中心距離容器最近的邊作為終止位置。
closest-corner漸變中心距離容器最近的角作為終止位置。
farthest-side漸變中心距離容器最遠的邊作為終止位置。
farthest-corner(預設值)漸變中心距離容器最遠的角作為終止位置。

當然,對於完全對稱的容器,closest-*farthest-*是完全相同的,各自的區別如下所示

image.png

可以得到這樣的效果

image.png

三、錐形漸變

下面再來繪製周圍的“扇形”。

其實就是幾個旋轉角度的矩形,在以前,這種矩形只能透過 dom 元素,利用 CSS transform才能實現。不過現在可以藉助錐形漸變來實現這樣的效果了

有興趣的可以參考之前這篇文章:錐形漸變只能畫圓錐嗎?conic-gradient 10大應用舉例

Kapture 2023-03-18 at 14.01.10.gif

在繪製之前,需要搞清楚背景的先後順序,一句話概括就是:

多背景的情況下,前面的背景層級 > 後面的背景層級

image.png

下面來繪製綠色的部分,其實是一個起始角度為 120deg,旋轉角度為90deg的錐形漸變

image.png

還有一個問題,旋轉中心並不是在圖形正中心,而是中間的圓三等分上的一個點,如果我們知道了中心點的位置還有偏移的角度,是不是可以算出旋轉中心點的位置?如下

image.png

根據以上位置關係,由於需要用的中間圓的半徑,所以可以用一個 CSS 變數來表示,用 CSS 實現就是

chrome{
  --size: 45%; /*用一個變數方便計算*/
  background: 
    background: radial-gradient( closest-side circle, #477EE6 calc(100% - 10px), #fff calc(100% - 9.5px) 100%, transparent calc(100% + .5px)) center/var(--size) no-repeat,
    /*綠色*/
    conic-gradient(from 210deg at calc( 50% + calc(var(--size) / 2) * cos(30deg) ) calc( 50% + calc(var(--size) / 2) * sin(30deg) ), #539E55 100deg, transparent 0)
    #F2C146
}

注意,現代瀏覽器(Chrome 111+) 已經支援了sincos數學函式

https://developer.mozilla.org/en-US/docs/Web/CSS/sin

當然,這裡也可以改成具體的數值,比如 cos(30deg) 約等於 0.866sin(30deg)等於0.5,所以可以改成

chrome{
  background: 
    background: radial-gradient( closest-side circle, #477EE6 calc(100% - 10px), #fff calc(100% - 9.5px) 100%, transparent calc(100% + .5px)) center/var(--size) no-repeat,
    /*綠色*/
    conic-gradient(from 210deg at calc( 50% + calc(var(--size) / 2) * 0.866) ) calc( 50% + calc(var(--size) / 2) * 0.5 ), #539E55 100deg, transparent 0)
    /*橙色底色*/
    #F2C146
}

效果如下

image.png

用同樣的方式可以繪製出紅色部分

chrome{
  background: 
    background: radial-gradient( closest-side circle, #477EE6 calc(100% - 10px), #fff calc(100% - 9.5px) 100%, transparent calc(100% + .5px)) center/var(--size) no-repeat,
    /*紅色*/
    conic-gradient(from 330deg at calc( 50% - calc(var(--size) / 2) * 0.866 ) calc( 50% + calc(var(--size) / 2) * .5 ), #D75442 100deg, transparent 0),
    /*綠色*/
    conic-gradient(from 210deg at calc( 50% + calc(var(--size) / 2) * 0.866) ) calc( 50% + calc(var(--size) / 2) * 0.5 ), #539E55 100deg, transparent 0)
    /*橙色底色*/
    #F2C146
}

效果如下

image.png

是不是有點像了?其實還紅色部分多了一點,需要用橙色蓋住,其實就是這樣

image.png

可以透過錐形漸變或者線性漸變實現,這裡採用錐形漸變實現

chrome{
  background: 
    
    background: radial-gradient( closest-side circle, #477EE6 calc(100% - 10px), #fff calc(100% - 9.5px) 100%, transparent calc(100% + .5px)) center/var(--size) no-repeat,
    /*橙色部分*/
    conic-gradient( #F2C146 90deg, transparent 0) 50% 50%/ 100% var(--size) no-repeat,
    /*紅色*/
    conic-gradient(from 330deg at calc( 50% - calc(var(--size) / 2) * 0.866 ) calc( 50% + calc(var(--size) / 2) * .5 ), #D75442 100deg, transparent 0),
    /*綠色*/
    conic-gradient(from 210deg at calc( 50% + calc(var(--size) / 2) * 0.866) ) calc( 50% + calc(var(--size) / 2) * 0.5 ), #539E55 100deg, transparent 0)
    /*橙色底色*/
    #F2C146
}

效果如下

image.png

最後設定圓角就行了~下面是完整程式碼

chrome{
  width: 200px;
  height: 200px;
  border-radius: 50%;
  --size: 45%;
  background: radial-gradient( closest-side circle, #477EE6 calc(100% - 10px), #fff calc(100% - 9.5px) 100%, transparent calc(100% + .5px)) center/var(--size) no-repeat,
    conic-gradient( #F2C146 90deg, transparent 0) 50% 50%/ 100% var(--size) no-repeat,
    conic-gradient(from 330deg at calc( 50% - calc(var(--size) / 2) * 0.866 ) calc( 50% + calc(var(--size) / 2) * .5 ), #D75442 100deg, transparent 0),
    conic-gradient(from 210deg at calc( 50% + calc(var(--size) / 2) * 0.866 ) calc( 50% + calc(var(--size) / 2) * .5 ), #539E55 100deg, transparent 0), 
    #F2C146
}

這樣就繪製出了一個 Chrome 圖示?

image.png

你也可以檢視以下任意連結:

四、總結一下

以上就是透過 CSS 漸變繪製出一個 Chrome 圖示的全部過程了,沒有用到任何額外標籤(包括偽元素),再次感嘆 CSS 漸變的強大。下面總結一下

  1. 複雜的圖形需要透過拆分轉換成熟悉的形狀
  2. 徑向漸變中的closest-side,表示最近的邊,可以根據背景尺寸直接控制圓的大小
  3. 多背景的情況下,前面的背景層級 > 後面的背景層級
  4. 以前旋轉的矩形只能透過 CSS transform才能實現,現在可以藉助錐形漸變來實現
  5. CSS 三角函式可以很方便的計算角度和位置的關係

最後,如果覺得還不錯,對你有幫助的話,歡迎點贊、收藏、轉發❤❤❤

歡迎關注我的公眾號:前端偵探

相關文章