您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)如何使用CSS Paint API動(dòng)態(tài)創(chuàng)建與分辨率無關(guān)的可變背景效果的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
現(xiàn)代Web應(yīng)用對(duì)圖像的需求量很大,它們占據(jù)網(wǎng)絡(luò)下載的大部分字節(jié)。通過優(yōu)化它們,你可以更好地利用它們的性能。如果你碰巧使用幾何圖形作為背景圖像,有一個(gè)替代方案:你可以使用 CSS Paint API [1] 以編程方式生成背景。
效果圖:
設(shè)置項(xiàng)目
首先,創(chuàng)建一個(gè)新的 index.html
文件,并編寫如下代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>:art: CSS Paint API</title> <link rel="stylesheet" href="styles.css" /> </head> <body> <textarea class="pattern"></textarea> <script> if ('paintWorklet' in CSS) { CSS.paintWorklet.addModule('pattern.js'); } </script> </body> </html>
有幾件事要注意:
在第13行,我們加載了一個(gè)新的Paint worklet。目前,全球支持率約為63%。因此,我們必須首先檢查是否支持 paintWorklet
。
我正在使用 textarea
進(jìn)行演示,因此我們可以看到調(diào)整畫布的大小將如何重繪圖案。
最后,你需要?jiǎng)?chuàng)建一個(gè) pattern.js
(用于注冊(cè)繪畫工作區(qū))以及一個(gè) styles.css
,我們可以在其中定義幾個(gè)樣式。
什么是worklet?
Paint worklet是一個(gè)定義了應(yīng)該畫在畫布上的內(nèi)容的類。它們的工作原理與 canvas
元素類似。如果你以前有這方面的知識(shí),代碼會(huì)看起來很熟悉。然而,它們并不是100%相同的。例如,在worklet中還不支持文本渲染方法。
在這里,我們還要定義CSS樣式。這是我們要使用worklet的地方:
.pattern { width: 250px; height: 250px; border: 1px solid #000; background-image: paint(pattern); }
我添加了一個(gè)黑色的邊框,這樣我們可以更好地看到 textarea
。要引用一個(gè)paint worklet,你需要把 paint(worklet-name)
作為一個(gè)值傳遞給 background-image
屬性。但是 pattern
是從哪里來的呢?我們還沒有定義它,所以讓我們把它作為我們的下一步。
定義Worklet
打開 pattern.js
并添加以下內(nèi)容:
class Pattern { paint(context, canvas, properties) { } } registerPaint('pattern', Pattern);
在這里可以使用 registerPaint
方法注冊(cè) paintWorklet
。你可以在此處定義的CSS中引用第一個(gè)參數(shù)。第二個(gè)參數(shù)是定義應(yīng)在canvas上繪畫的類。它具有一個(gè)包含三個(gè)參數(shù)的 paint
方法:
context PaintRenderingContext2D CanvasRenderingContext2D API
canvas
:這是我們的canvas,一個(gè) PaintSize
對(duì)象,只有兩個(gè)屬性:width和height。
properties
:這將返回一個(gè) StylePropertyMapReadOnly
對(duì)象,我們可以使用該對(duì)象通過JavaScript讀取CSS屬性及其值。
繪制矩形
下一步是顯示一些東西,所以讓我們繪制矩形。將以下內(nèi)容添加到 paint
方法中:
paint(context, canvas, properties) { for (let x = 0; x < canvas.height / 20; x++) { for (let y = 0; y < canvas.width / 20; y++) { const bgColor = (x + y) % 2 === 0 ? '#FFF' : '#FFCC00'; context.shadowColor = '#212121'; context.shadowBlur = 10; context.shadowOffsetX = 10; context.shadowOffsetY = 1; context.beginPath(); context.fillStyle = bgColor; context.rect(x * 20, y * 20, 20, 20); context.fill(); } } }
我們?cè)谶@里所做的就是創(chuàng)建一個(gè)嵌套循環(huán),以循環(huán)遍歷畫布的寬度和高度。由于矩形的大小為20,因此我們要將矩形的高度和寬度除以20。
在第4行,我們可以使用模數(shù)運(yùn)算符在兩種顏色之間切換。我還為深度添加了一些陰影。最后,我們?cè)诋嫴忌侠L制矩形。如果在瀏覽器中打開它,則應(yīng)具有以下內(nèi)容:
使背景動(dòng)態(tài)化
遺憾的是,除了調(diào)整 textarea
的大小和一窺Paint API是如何重繪一切的,這大部分還是靜態(tài)的。所以,讓我們通過添加我們可以改變的自定義CSS屬性來讓事情變得更加動(dòng)態(tài)。
打開你的 styles.css
并在其中添加以下幾行:
.pattern { width: 250px; height: 250px; border: 1px solid #000; background-image: paint(pattern); + --pattern-color: #FFCC00; + --pattern-size: 23; + --pattern-spacing: 0; + --pattern-shadow-blur: 10; + --pattern-shadow-x: 10; + --pattern-shadow-y: 1; }
你可以通過在CSS屬性前加上 —
來定義自定義CSS屬性。這些屬性可以被 var()
函數(shù)使用。但在我們的案例中,我們將在我們的paint worklet中使用它。
在CSS中檢查支持
為確保支持Paint API,我們還可以檢查CSS中的支持。為此,我們有兩個(gè)選擇:
使用 @supports
規(guī)則守護(hù)規(guī)則。
使用后備背景圖片。
/* 第一種選擇 */ @supports (background: paint(pattern)) { /** * 如果該部分得到評(píng)估,則意味著Paint API 支持 **/ } /** * 第二種選擇 * 如果支持Paint API,后一條規(guī)則將覆蓋第一條規(guī)則。 * 如果不支持,CSS將使其無效,并將應(yīng)用url()的規(guī)則。 **/ .pattern { background-image: url(pattern.png); background-image: paint(pattern); }
訪問繪畫worklet中的參數(shù)
要讀取 pattern.js
中的這些參數(shù),您需要向定義paint worklet的類中添加一個(gè)新方法:
class Pattern { // `inputProperties`方法返回的任何東西,paint worklet都可以訪問。 static get inputProperties() { return [ '--pattern-color', '--pattern-size', '--pattern-spacing', '--pattern-shadow-blur', '--pattern-shadow-x', '--pattern-shadow-y' ]; } }
要在 paint
方法內(nèi)部訪問這些屬性,可以使用 properties.get
:
paint(context, canvas, properties) { const props = { color: properties.get('--pattern-color').toString().trim(), size: parseInt(properties.get('--pattern-size').toString()), spacing: parseInt(properties.get('--pattern-spacing').toString()), shadow: { blur: parseInt(properties.get('--pattern-shadow-blur').toString()), x: parseInt(properties.get('--pattern-shadow-x').toString()), y: parseInt(properties.get('--pattern-shadow-y').toString()) } }; }
對(duì)于顏色,我們需要將其轉(zhuǎn)換為字符串。其他所有內(nèi)容都需要轉(zhuǎn)換為數(shù)字。這是因?yàn)?properties.get
返回 CSSUnparsedValue
。
properties.get的返回值
為了使內(nèi)容更具可讀性,我創(chuàng)建了兩個(gè)新函數(shù)來為我們處理解析:
paint(context, canvas, properties) { const getPropertyAsString = property => properties.get(property).toString().trim(); const getPropertyAsNumber = property => parseInt(properties.get(property).toString()); const props = { color: getPropertyAsString('--pattern-color'), size: getPropertyAsNumber('--pattern-size'), spacing: getPropertyAsNumber('--pattern-spacing'), shadow: { blur: getPropertyAsNumber('--pattern-shadow-blur'), x: getPropertyAsNumber('--pattern-shadow-x'), y: getPropertyAsNumber('--pattern-shadow-y') } }; }
現(xiàn)在我們要做的就是用相應(yīng)的 prop
值替換for循環(huán)中的所有內(nèi)容:
for (let x = 0; x < canvas.height / props.size; x++) { for (let y = 0; y < canvas.width / props.size; y++) { const bgColor = (x + y) % 2 === 0 ? '#FFF' : props.color; context.shadowColor = '#212121'; context.shadowBlur = props.shadow.blur; context.shadowOffsetX = props.shadow.x; context.shadowOffsetY = props.shadow.y; context.beginPath(); context.fillStyle = bgColor; context.rect(x * (props.size + props.spacing), y * (props.size + props.spacing), props.size, props.size); context.fill(); } }
現(xiàn)在回到你的瀏覽器,試著改變一下。
在DevTools中編輯背景 總結(jié)
為什么CSS Paint API對(duì)我們有用?有哪些用例?
最明顯的是,它減小了響應(yīng)的大小。通過消除圖像的使用,你可以節(jié)省一個(gè)網(wǎng)絡(luò)請(qǐng)求和幾千字節(jié)。這樣可以提高性能。
對(duì)于使用DOM元素的復(fù)雜CSS效果,你還可以減少頁(yè)面上的節(jié)點(diǎn)數(shù)量。因?yàn)槟憧梢杂肞aint API創(chuàng)建復(fù)雜的動(dòng)畫,所以不需要額外的空節(jié)點(diǎn)。
在我看來,最大的好處是它的可定制性遠(yuǎn)高于靜態(tài)背景圖片。API還可以創(chuàng)建與分辨率無關(guān)的圖像,所以你不用擔(dān)心錯(cuò)過單一屏幕尺寸。
如果你今天選擇使用CSS Paint API,請(qǐng)確保你提供polyfill,因?yàn)樗匀粵]有被廣泛采用。如果你想調(diào)整完成的項(xiàng)目,你可以從這個(gè) GitHub倉(cāng)庫(kù) [2] 中克隆它。
廣深鑄就宏篇 :論深,本書深究JS之所以然,舉世無可出其右;論廣,本書遍歷語義之細(xì)部,看罷再無機(jī)理之惑。
超語言之思想 :萬法歸宗異曲同工,剝?nèi)S外殼,本書居高處辨析語言?shī)W義的技術(shù)大局觀,適用于所有編程語言。
修煉重在重學(xué) :混合App|Node服務(wù)端|FaaS云原生|前端智能化時(shí)代,回歸本質(zhì)重修這門基礎(chǔ)課才能走得更遠(yuǎn)更快。
感謝各位的閱讀!關(guān)于“如何使用CSS Paint API動(dòng)態(tài)創(chuàng)建與分辨率無關(guān)的可變背景效果”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。