自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

萬(wàn)能的CSS 漸變!單標(biāo)簽繪制一個(gè)足球場(chǎng)

開(kāi)發(fā) 前端
漸變是 CSS 中非常強(qiáng)大但比較繁瑣的功能了,幾乎是萬(wàn)能的,能夠設(shè)計(jì)出來(lái)的都可以通過(guò)漸變繪制出來(lái),只是實(shí)現(xiàn)的復(fù)雜度問(wèn)題,擅于發(fā)現(xiàn)圖形的規(guī)律也能有效地減少漸變的復(fù)雜度。

世界杯正在進(jìn)行中,也不要忘記學(xué)習(xí) CSS(得想辦法蹭一波熱度)。比如,用 CSS 繪制一個(gè)足球場(chǎng)?

圖片

CSS 足球場(chǎng)

一眼望去,這里的形狀只有圓形和矩形,在不借助其他標(biāo)簽的情況下(包括偽元素),其實(shí)很容易聯(lián)想到漸變,一起看看如何繪制的吧,有非常多的漸變小技巧~

溫馨提示:文章中帶有“??”的描述屬于足球小知識(shí),不感興趣的可以跳過(guò),與 CSS 無(wú)關(guān)。

一、場(chǎng)地的尺寸設(shè)計(jì)

首先來(lái)看一下足球場(chǎng)的構(gòu)造,下面是在網(wǎng)上找到的一張?jiān)O(shè)計(jì)圖。

圖片

球場(chǎng)設(shè)計(jì)圖

主要有以下幾個(gè)部分:

  1. 整體是矩形,邊線和底線,長(zhǎng)度是 109~131碼(90~120m),寬度是 49-98碼(45~90m)。
  2. 中線,貫穿球場(chǎng)。
  3. 開(kāi)球點(diǎn),位于中線的中心。
  4. 中圈,以開(kāi)球點(diǎn)為圓形,半徑為 10碼(9.15m)圓。
  5. 罰球區(qū)(大禁區(qū)),長(zhǎng)度是44碼(40.3m),寬度是18碼(16.5m)。
  6. 球門區(qū)(小禁區(qū)),長(zhǎng)度是20碼(18.3m),寬度是6碼(5.5m)。
  7. 球門,長(zhǎng)度是8碼(7.32m)。
  8. 罰球點(diǎn)(點(diǎn)球點(diǎn)),距離球門12碼(11m)。
  9. 罰球?。ń麉^(qū)?。?,以罰球點(diǎn)為圓心,半徑為 10碼(9.15m)的圓弧。
  10. 角球區(qū),以4個(gè)角為圓心,半徑為 1m的 1/4 圓弧。

??現(xiàn)代足球運(yùn)動(dòng)起源于英國(guó),當(dāng)時(shí)英制的長(zhǎng)度單位是“碼”,1碼等于0.9144米,約0.915米。 那么,英制長(zhǎng)度10碼換算成公制長(zhǎng)度就是9.15米。 這就是9.15米的來(lái)源。

二、邊線和底線

以世界杯比賽場(chǎng)地為例,長(zhǎng)度115碼(105m),寬度74碼(68m)。

??2022世界杯決賽將在盧賽爾球場(chǎng)舉行,它由中國(guó)鐵建國(guó)際集團(tuán)承建。

假設(shè) HTML結(jié)構(gòu)如下,這里用到的標(biāo)簽僅僅只有一個(gè)。

<filed></filed>

為了尺寸計(jì)算方便,采用em相對(duì)單位進(jìn)行換算,數(shù)值就可以采用真實(shí)的“碼”,好處是都是整數(shù),簡(jiǎn)單繪制一下外圍邊線和底線,如下:

filed{
font-size: 5px;
width: 115em; /*表示115碼*/
height: 74em;
border: 5em solid transparent;
outline: 2px solid #fff;/*線寬就用固定值*/
outline-offset: -5em;
background: #43A63C;
}

注意這里實(shí)現(xiàn)的小細(xì)節(jié):這里外層的線框是通過(guò)outline實(shí)現(xiàn)的,還預(yù)留了一個(gè)5em的透明邊框,這是因?yàn)楸尘暗奈恢煤统叽绨俜直扔?jì)算是根據(jù)內(nèi)容區(qū)域的,并不包含邊框。比如,background-postion:0 0表示的就是線框內(nèi)的左上點(diǎn),background-postion: 100% 100%表示的就是線框內(nèi)的右下點(diǎn),,background-size: 100%表示的就是線框內(nèi)最大尺寸,如下:

圖片

透明邊框的好處

還有一個(gè)好處,透明邊框仍然是可以繪制背景的,比如深淺不同的草皮就可以繪制在邊框之外,這個(gè)后面再說(shuō)。

準(zhǔn)備工作完成了,下面是具體的繪制過(guò)程。

三、中線、開(kāi)球點(diǎn)和中圈

在繪制之前,可以簡(jiǎn)單規(guī)劃一下,通過(guò) CSS 變量將各部分分離開(kāi)來(lái),這樣看起來(lái)會(huì)更加清晰,例如:

filed{
--中線: xxx;
--中圈開(kāi)球點(diǎn): xxx;
...
background:
/*越靠前的背景越靠上*/
var(--中線),
var(--中圈開(kāi)球點(diǎn)),
...,
#43A63C
}

這個(gè)技巧在之前這篇文章中有相關(guān)介紹:??由 transform 被占用引發(fā)的思考????

首先是中線,使用線性漸變linear-gradient。

--中線: linear-gradient(#fff, #fff) center/2px 100% no-repeat;

可能有些同學(xué)還不太清楚上面這一段 background的簡(jiǎn)寫,可以看下面這張圖(下面只列舉了常用的,實(shí)際上還有更多屬性)。

圖片

背景的簡(jiǎn)寫

效果如下:

圖片

中線

然后是開(kāi)球點(diǎn)和中圈。

??球在開(kāi)出前,其他隊(duì)員不得進(jìn)入中圈。

這是一個(gè)半徑為10碼的圓,可以通過(guò)一個(gè)徑向漸變r(jià)adial-gradient實(shí)現(xiàn)。

--中圈: radial-gradient( closest-side circle, #fff 2px, transparent 0 calc(100% - 2px), #fff 0 100%, transparent 0) center/20em 20em no-repeat;

注意,這里使用了關(guān)鍵詞closest-side,表示最近的邊,可以根據(jù)背景尺寸直接控制圓的大小,默認(rèn)值是farthest-side,其他選項(xiàng)詳細(xì)如下:

關(guān)鍵字

描述

closest-side

漸變中心距離容器最近的邊作為終止位置。

closest-corner

漸變中心距離容器最近的角作為終止位置。

farthest-side

漸變中心距離容器最遠(yuǎn)的邊作為終止位置。

??farthest-corner(默認(rèn)值)??

漸變中心距離容器最遠(yuǎn)的角作為終止位置。

當(dāng)然,對(duì)于完全對(duì)稱的容器,closest-* 和 farthest-*是完全相同的,各自的區(qū)別如下所示:

圖片

徑向漸變關(guān)鍵詞

繪制效果如下:

圖片

中圈

四、罰球區(qū)、球門區(qū)

罰球區(qū)通常也叫大禁區(qū),是一個(gè)44碼*18碼的矩形線框。

??守門員在罰球區(qū)內(nèi)可以用手觸球,出去就不行了,還有就是在這個(gè)區(qū)域犯規(guī),容易被判點(diǎn)球。

線性漸變不像徑向漸變那樣,并不能直接畫出這種矩形線框,我采用的方式是覆蓋的方式,也就是一塊綠色的覆蓋在一塊白色的背景之上,實(shí)現(xiàn)如下:

--大禁區(qū): linear-gradient(#43A63C, #43A63C) left center/calc(18em - 2px) calc(44em - 4px) no-repeat, linear-gradient(#fff, #fff) left center/18em 44em no-repeat;

動(dòng)態(tài)演示如下:

圖片

大禁區(qū)實(shí)現(xiàn)演示

兩邊半場(chǎng)都有罰球區(qū)域,而且長(zhǎng)的也完全一樣,需要再重新繪制一份一模一樣的嗎?

??????當(dāng)然不需要!

凡事看到相同或相似的圖案都需要考慮能否避免重復(fù)的工作量?

仔細(xì)觀察,兩邊的罰球區(qū)域正好可以通過(guò)水平平鋪repeat-x實(shí)現(xiàn),只需要改變背景大小就行了,示意如下:

圖片

平鋪實(shí)現(xiàn)演示

你也可以查看動(dòng)態(tài)演示:

圖片

平鋪實(shí)現(xiàn)動(dòng)態(tài)演示

用代碼實(shí)現(xiàn)就是:

--大禁區(qū): linear-gradient(to right, #43A63C calc(18em - 2px), transparent 0) 0 center/calc(100% - 18em + 2px) calc(44em - 4px) repeat-x, linear-gradient(to right, #fff 18em, transparent 0) 0 center/calc(100% - 18em) 44em repeat-x;

這樣就能在不增加漸變數(shù)量的情況下實(shí)現(xiàn)多份相同的背景,效果如下:

圖片

大禁區(qū)

然后是球門區(qū),通常叫小禁區(qū),是一個(gè)20碼*6碼的矩形線框。

??球門球時(shí),由守方隊(duì)員在球門區(qū)內(nèi)任意一點(diǎn)將球放定后踢出。

這個(gè)和罰球區(qū)繪制方法一致,就不多描述了。

--小禁區(qū): linear-gradient(to right, #43A63C calc(6em - 2px), transparent 0) 0 center/calc(100% - 6em + 2px) calc(20em - 4px) repeat-x, linear-gradient(to right, #fff 6em, transparent 0) 0 center/calc(100% - 6em) 20em repeat-x;

效果如下:

圖片

小禁區(qū)

最后是球門。球門在底線后面,由于是俯視圖,只需要知道長(zhǎng)度8碼就行了,寬度可以隨便給一個(gè)。

??足球要完全越過(guò)門線才算進(jìn)球,僅超過(guò)1/2也不行。

這個(gè)和上面繪制方法一致,不過(guò)需要注意background-position的位置,是負(fù)數(shù)。

--球門: linear-gradient(to right, #43A63C calc(3em - 4px), transparent 0) calc(-3em + 2px) center/calc(100% + 3em) calc(8em - 4px) repeat-x, linear-gradient(to right, #fff 3em, transparent 0) -3em center/calc(100% + 3em) 8em repeat-x;

這里就體現(xiàn)出前面透明的好處了,可以將背景繪制在邊框上,效果如下:

圖片

球門

這樣就完成了所有矩形線框的繪制。

五、罰球點(diǎn)、罰球弧、角球弧

最后是幾條比較重要的圓弧。

首先是罰球點(diǎn),又稱點(diǎn)球點(diǎn),距離球門12碼。

??這個(gè)相信很多人都知道,12碼點(diǎn)球主罰的地方就是這里。

這是一個(gè)圓點(diǎn),直接通過(guò)一個(gè)徑向漸變r(jià)adial-gradient繪制,這個(gè)我們等會(huì)再來(lái)繪制,先畫下面的。

然后是罰球弧,它是以罰球點(diǎn)為圓心,半徑為10碼的圓弧,和中圈一樣。

??在罰點(diǎn)球時(shí),除守方守門員和主罰隊(duì)員外,雙方其他隊(duì)員都必須退出罰球區(qū)及罰球弧外,因?yàn)榈搅P球點(diǎn)的距離都是 10 碼。

和中圈大小是一樣的,只是位置不同,注意圓心距離左側(cè)的距離是12碼,由于左右都是一樣的,可以用前面提到的repeat-x方式實(shí)現(xiàn)(當(dāng)然這里不寫也行,因?yàn)槟J(rèn)就是平鋪的),示意如下:

圖片

平鋪實(shí)現(xiàn)演示

你也可以查看動(dòng)態(tài)演示:

圖片

平鋪實(shí)現(xiàn)動(dòng)態(tài)演示

用代碼實(shí)現(xiàn)就是:

--罰球弧: radial-gradient( circle at 12em center, transparent calc(10em - 2px), #fff 0 10em, transparent 0) 0 center/calc(100% - 24em) 100%;

效果如下:

圖片

最上層的罰球弧

現(xiàn)在這個(gè)圓弧覆蓋在最上面,由于罰球區(qū)是通過(guò)覆蓋的方式實(shí)現(xiàn)的,所以可以將罰球弧放在罰球區(qū)下面,通過(guò)改變background的先后順序就可以了,如下:

多背景的情況下,前面的背景層級(jí) > 后面的背景層級(jí)。

background: 
/* var(--罰球弧), */
var(--小禁區(qū)),
var(--大禁區(qū)),
var(--罰球弧), /* 將罰球弧移動(dòng)到大禁區(qū)下面*/
var(--球門),
var(--中線),
var(--中圈),
#43A63C;
}

這樣就正常了。

圖片

罰球弧

然后用同樣的方式把罰球點(diǎn)補(bǔ)上。

--罰球點(diǎn): radial-gradient( circle at 12em center, #fff 2px, transparent 0) 0 center/calc(100% - 24em) 100%;

效果如下:

圖片

?罰球點(diǎn)

最后是角球弧。位于球場(chǎng)四角,是半徑為1m的 1/4 圓弧。

??用來(lái)發(fā)角球的地方,守方隊(duì)員在己方半場(chǎng)將球自底線處踢出界外,攻方獲得的就是發(fā)角球的機(jī)會(huì)

如果按照一般的思路,肯定是繪制 4 個(gè) 1/4 圓弧就行了,不過(guò)這里還可以采用另一種方式。仔細(xì)想一下,這4個(gè)圓弧合在一起是不是剛好就是一個(gè)完整的圓?經(jīng)過(guò)位移、平鋪就可以了,思路演示如下

這個(gè)思路在之前這篇文章中有用到:??CSS 實(shí)現(xiàn)優(yōu)惠券的技巧??

圖片

1/4圓平鋪原理演示

用代碼實(shí)現(xiàn)就是:

--角球弧: radial-gradient( circle at 1em 1em, transparent calc(1em - 2px), #fff 0 1em, transparent 0) -1em -1em/100% 100%;

這樣用一個(gè)漸變就同時(shí)繪制出了4個(gè)圓,效果如下:

圖片

4個(gè)完整角球弧

可以看到,4個(gè)圓弧已經(jīng)均勻分布在4個(gè)角落了,但是已經(jīng)超出了線外,這個(gè)也非常好解決,默認(rèn)情況下背景是可以繪制在border-box范圍內(nèi)的,只需要通過(guò)background-clip裁剪到content-box內(nèi)就行了,如下:

--角球弧: radial-gradient( circle at 1em 1em, transparent calc(1em - 2px), #fff 0 1em, transparent 0) -1em -1em/100% 100% content-box;/*添加裁剪區(qū)域*/

這樣就完美了。

圖片

使用background-clip裁剪后的角球弧

六、草坪

到目前位置,球場(chǎng)的所有部分基本已經(jīng)完成了,最后再鋪上深淺相間的草坪。

??不僅僅是為了好看,還能緩解觀眾和球員的視覺(jué)疲勞,同時(shí)也方便裁判和球員看清是否越位。

關(guān)于草坪的條紋間隔貌似不是很統(tǒng)一?這里就大概給一個(gè)數(shù)值,用線性漸變即可,如下:

--草坪: linear-gradient(90deg, transparent 50%, rgba(0,0,0,.4) 0% 100%) center/10% 100%;

由于前面罰球區(qū)等用到了覆蓋的方式,所以這里不能直接將草坪繪制在最底下,需要繪制在最上層,效果如下:

圖片

直接覆蓋的草坪

可以看到,僅僅通過(guò)半透明的覆蓋還是很不自然的,所以需要將顏色混合一下,需要用到background-blend-mode,比較復(fù)雜,這里就不展開(kāi)了,設(shè)置如下:

overlay,soft-light,hard-light屬于融合混合模式,比較適合這類情況。

background-blend-mode: soft-light /*柔光*/

效果如下:

圖片

混合模式

有點(diǎn)奇怪...原因是上面設(shè)置的是所有圖層的background-blend-mode,我們其實(shí)只需要設(shè)置最頂層的草坪,那怎么處理呢?我起初以為background縮寫是包含background-blend-mode的,這樣的話可以單獨(dú)給某一層設(shè)置了,可惜這個(gè)不支持(我猜測(cè)這個(gè)屬性出現(xiàn)的稍晚一些,沒(méi)有統(tǒng)一到背景里)。

沒(méi)辦法,只能逐層設(shè)置了,第1層設(shè)置 soft-light,剩下的全部都是normal,如下:

background-blend-mode: soft-light, normal,...,normal;

后面的normal可以多,但是不能少,原因在于,會(huì)根據(jù)背景數(shù)量自動(dòng)補(bǔ)充,如果數(shù)量不足,會(huì)重新開(kāi)頭循環(huán)(這個(gè)補(bǔ)充規(guī)則其實(shí)跟其他背景屬性,例如 background-size是一樣的)。

圖片

混合模式自動(dòng)填充規(guī)則

這樣就非常自然了,效果如下:

圖片

最終效果

下面是完整代碼(其實(shí)沒(méi)多少行):

filed{
font-size: 5px;
width: 115em;
height: 74em;
--中線: linear-gradient(#fff, #fff) center/2px 100% no-repeat;
--中圈: radial-gradient( closest-side circle, #fff 2px, transparent 0 calc(100% - 2px), #fff 0 100%, transparent 0) center/20em 20em no-repeat;
--大禁區(qū): linear-gradient(to right, #43A63C calc(18em - 2px), transparent 0) 0 center/calc(100% - 18em + 2px) calc(44em - 4px) repeat-x, linear-gradient(to right, #fff 18em, transparent 0) 0 center/calc(100% - 18em) 44em repeat-x;
--小禁區(qū): linear-gradient(to right, #43A63C calc(6em - 2px), transparent 0) 0 center/calc(100% - 6em + 2px) calc(20em - 4px) repeat-x, linear-gradient(to right, #fff 6em, transparent 0) 0 center/calc(100% - 6em) 20em repeat-x;
--球門: linear-gradient(to right, #43A63C calc(3em - 4px), transparent 0) calc(-3em + 2px) center/calc(100% + 3em) calc(8em - 4px) repeat-x, linear-gradient(to right, #fff 3em, transparent 0) -3em center/calc(100% + 3em) 8em repeat-x;
--罰球弧: radial-gradient( circle at 12em center, transparent calc(10em - 2px), #fff 0 10em, transparent 0) 0 center/calc(100% - 24em) 100%;
--罰球點(diǎn): radial-gradient( circle at 12em center, #fff 2px, transparent 0) 0 center/calc(100% - 24em) 100%;
--角球弧: radial-gradient( circle at 1em 1em, transparent calc(1em - 2px), #fff 0 1em, transparent 0) -1em -1em/100% 100% content-box;
--草坪: linear-gradient(90deg, transparent 50%, rgba(0,0,0,.5) 0% 100%) center/10% 100%;
background:
var(--草坪),
var(--角球弧),
var(--罰球點(diǎn)),
var(--球門),
var(--小禁區(qū)),
var(--大禁區(qū)),
var(--罰球弧),
var(--中線),
var(--中圈),
#43A63C;
background-blend-mode: soft-light, normal, normal, normal, normal, normal, normal, normal, normal, normal, normal, normal;
border: 5em solid transparent;
outline: 2px solid #fff;
outline-offset: -5em;
}

你也可以訪問(wèn)以下任意鏈接:

  • CSS football filed - 碼上掘金 (juejin.cn)[1]
  • CSS football filed (codepen.io)[2]
  • CSS football filed (runjs.work)[3]

七、總結(jié)一下

漸變是 CSS 中非常強(qiáng)大但比較繁瑣的功能了,幾乎是萬(wàn)能的,能夠設(shè)計(jì)出來(lái)的都可以通過(guò)漸變繪制出來(lái),只是實(shí)現(xiàn)的復(fù)雜度問(wèn)題,擅于發(fā)現(xiàn)圖形的規(guī)律也能有效地減少漸變的復(fù)雜度,下面簡(jiǎn)單總結(jié)一下。

  1. 背景的位置和尺寸的百分比計(jì)算是根據(jù)內(nèi)容區(qū)域的,并不包含邊框。
  2. 透明邊框仍然是可以繪制背景的。
  3. 通過(guò) CSS 變量將背景各部分分離開(kāi)來(lái),這樣看起來(lái)會(huì)更加清晰。
  4. 線性漸變不像徑向漸變那樣,并不能直接畫出這種矩形線框,可以用兩層漸變覆蓋的方式實(shí)現(xiàn)。
  5. 凡事看到相同或相似的圖案都可以考慮使用背景平鋪來(lái)減少工作量。
  6. 多背景的情況下,前面的背景層級(jí) > 后面的背景層級(jí)。
  7. 4 個(gè) 1/4圓可以通過(guò)一個(gè)完整的圓位移平鋪實(shí)現(xiàn)。
  8. 默認(rèn)情況下背景是可以繪制在邊框范圍內(nèi)的,可以通過(guò)background-clip改變繪制范圍。
  9. 背景混合模式并不在background簡(jiǎn)寫屬性中,需要單獨(dú)書寫,可以讓圖層混合更加自然。
  10. 背景混合模式會(huì)根據(jù)背景數(shù)量自動(dòng)補(bǔ)充,如果數(shù)量不足,會(huì)重新開(kāi)頭循環(huán)。

當(dāng)然實(shí)際工作中肯定是不推薦的,更多是學(xué)習(xí)掌握漸變相關(guān)知識(shí),這樣繪制一些活動(dòng)小圖標(biāo),或者在某些不方便改變 HTML 結(jié)構(gòu)時(shí)可以有更多的思路和方案,不是嗎?

參考資料

[1]CSS football filed - 碼上掘金 (juejin.cn): ??https://code.juejin.cn/pen/7172148336886022175。??

[2]CSS football filed (codepen.io): ??https://codepen.io/xboxyan/pen/BaVqogP。??

[3]CSS football filed (runjs.work): ??https://runjs.work/projects/8f18caa4fb1248dc。??

責(zé)任編輯:姜華 來(lái)源: 前端偵探
相關(guān)推薦

2012-09-27 18:04:53

NEC巴西足球場(chǎng)館ICT

2017-03-15 18:43:46

華為

2024-03-06 11:16:10

2023-03-22 09:00:38

2024-12-09 09:25:30

2023-05-08 09:08:33

CSS前端

2023-07-17 09:19:20

CSSCSS 漸變

2009-11-06 09:44:11

Apache

2010-09-30 10:13:55

超算HPC

2016-11-24 12:07:42

Android萬(wàn)能圓角ImageView

2020-12-23 11:14:49

人工智能銷售行業(yè)AI

2009-12-03 18:13:36

PHP萬(wàn)能密碼

2011-06-16 15:57:25

Android

2022-11-30 13:13:41

節(jié)能減碳PUE

2014-02-17 10:56:21

Hadoop

2022-06-27 08:36:08

PythonLambda

2009-02-27 13:48:00

Mdaemon郵件服務(wù)器

2022-06-23 18:10:15

多云

2020-06-16 08:32:00

人工智能技術(shù)機(jī)器學(xué)習(xí)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)