用js监控分辨率调整背景图片宽度_如何使用CSS Paint API动态创建与分辨率无关的可变背景
現代Web應用對圖像的需求量很大,它們占據網絡下載的大部分字節。通過優化它們,你可以更好地利用它們的性能。如果你碰巧使用幾何圖形作為背景圖像,有一個替代方案:你可以使用CSS Paint API以編程方式生成背景。
在本教程中,我們將探討其功能,并探討如何使用它來動態創建與分辨率無關的動態背景。這將是本教程的輸出:
設置項目
首先,創建一個新的 index.html 文件,并編寫如下代碼:
<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title> 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行,我們加載了一個新的Paint worklet。目前,全球支持率約為63%。因此,我們必須首先檢查是否支持 paintWorklet。
- 我正在使用 textarea 進行演示,因此我們可以看到調整畫布的大小將如何重繪圖案。
- 最后,你需要創建一個 pattern.js(用于注冊繪畫工作區)以及一個 styles.css,我們可以在其中定義幾個樣式。
什么是worklet?
Paint worklet是一個定義了應該畫在畫布上的內容的類。它們的工作原理與 canvas 元素類似。如果你以前有這方面的知識,代碼會看起來很熟悉。然而,它們并不是100%相同的。例如,在worklet中還不支持文本渲染方法。
在這里,我們還要定義CSS樣式。這是我們要使用worklet的地方:
.pattern {width: 250px;height: 250px;border: 1px solid #000;background-image: paint(pattern); }我添加了一個黑色的邊框,這樣我們可以更好地看到 textarea。要引用一個paint worklet,你需要把 paint(worklet-name) 作為一個值傳遞給 background-image 屬性。但是 pattern 是從哪里來的呢?我們還沒有定義它,所以讓我們把它作為我們的下一步。
定義Worklet
打開 pattern.js 并添加以下內容:
class Pattern {paint(context, canvas, properties) {} }registerPaint('pattern', Pattern);在這里可以使用 registerPaint 方法注冊paintWorklet。你可以在此處定義的CSS中引用第一個參數。第二個參數是定義應在canvas上繪畫的類。它具有一個包含三個參數的 paint 方法:
- context:這將返回一個 PaintRenderingContext2D 對象,該對象實現 CanvasRenderingContext2D API 的子集。
- canvas:這是我們的canvas,一個 PaintSize 對象,只有兩個屬性:width和height。
- properties:這將返回一個 StylePropertyMapReadOnly 對象,我們可以使用該對象通過JavaScript讀取CSS屬性及其值。
繪制矩形
下一步是顯示一些東西,所以讓我們繪制矩形。將以下內容添加到 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();}} }我們在這里所做的就是創建一個嵌套循環,以循環遍歷畫布的寬度和高度。由于矩形的大小為20,因此我們要將矩形的高度和寬度除以20。
在第4行,我們可以使用模數運算符在兩種顏色之間切換。我還為深度添加了一些陰影。最后,我們在畫布上繪制矩形。如果在瀏覽器中打開它,則應具有以下內容:
使背景動態化
遺憾的是,除了調整 textarea 的大小和一窺Paint API是如何重繪一切的,這大部分還是靜態的。所以,讓我們通過添加我們可以改變的自定義CSS屬性來讓事情變得更加動態。
打開你的 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() 函數使用。但在我們的案例中,我們將在我們的paint worklet中使用它。
在CSS中檢查支持
為確保支持Paint API,我們還可以檢查CSS中的支持。為此,我們有兩個選擇:
- 使用 @supports 規則守護規則。
- 使用后備背景圖片。
訪問繪畫worklet中的參數
要讀取 pattern.js 中的這些參數,您需要向定義paint worklet的類中添加一個新方法:
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 方法內部訪問這些屬性,可以使用 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())}}; }對于顏色,我們需要將其轉換為字符串。其他所有內容都需要轉換為數字。這是因為 properties.get 返回 CSSUnparsedValue。
為了使內容更具可讀性,我創建了兩個新函數來為我們處理解析:
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')}}; }現在我們要做的就是用相應的 prop 值替換for循環中的所有內容:
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();} }現在回到你的瀏覽器,試著改變一下。
總結
為什么CSS Paint API對我們有用?有哪些用例?
最明顯的是,它減小了響應的大小。通過消除圖像的使用,你可以節省一個網絡請求和幾千字節。這樣可以提高性能。
對于使用DOM元素的復雜CSS效果,你還可以減少頁面上的節點數量。因為你可以用Paint API創建復雜的動畫,所以不需要額外的空節點。
在我看來,最大的好處是它的可定制性遠高于靜態背景圖片。API還可以創建與分辨率無關的圖像,所以你不用擔心錯過單一屏幕尺寸。
如果你今天選擇使用CSS Paint API,請確保你提供polyfill,因為它仍然沒有被廣泛采用。如果你想調整完成的項目,你可以從這個GitHub倉庫中克隆它。
來源:https://medium.com/better-programming,作者:Ferenc Almasi,翻譯:公眾號《前端全棧開發者》
總結
以上是生活随笔為你收集整理的用js监控分辨率调整背景图片宽度_如何使用CSS Paint API动态创建与分辨率无关的可变背景的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 七彩虹预告新款 iGame Lab 显卡
- 下一篇: CoffeeScript简介 <一