CSS Paint API

Chrome 65 新增無限可能

CSS Paint API (又稱「CSS 自訂顏料」或「Houdini 油漆工」) 是 。是什麼?您可以做些什麼 該怎麼辦?運作方式繼續往下看吧...」

CSS Paint API 可讓你透過程式輔助,在 CSS 供應商的協助下產生圖片 則會傳回圖片。例如 background-imageborder-image 等屬性 通常與 url() 搭配使用,以載入圖片檔或內建 CSS 例如 linear-gradient()在這之前,您可以改用 paint(myPainter) 用於參照油漆工人

創作顏料畫

如要定義名為 myPainter 的油漆廠,我們必須載入 CSS 油漆 使用 CSS.paintWorklet.addModule('my-paint-worklet.js') 建立 Worklet 檔案在這個例子中 檔案,我們可以使用 registerPaint 函式註冊油漆 Worklet 類別:

class MyPainter {
  paint(ctx, geometry, properties) {
    // ...
  }
}

registerPaint('myPainter', MyPainter);

paint() 回呼中,我們可以和以下程式碼一樣使用 ctx: 如同「<canvas>」所知的CanvasRenderingContext2D。若您知道 在 <canvas> 中繪製,就可在顏料畫中繪圖!geometry 告訴我們 畫布的寬度和高度properties,我將 我們會在本文稍後說明

我們以棋盤格顏料做成的入門範例 做為 <textarea> 的背景圖片。(我之所以使用文字區域,是因為 預設可調整大小):

<!-- index.html -->
<!doctype html>
<style>
  textarea {
    background-image: paint(checkerboard);
  }
</style>
<textarea></textarea>
<script>
  CSS.paintWorklet.addModule('checkerboard.js');
</script>
// checkerboard.js
class CheckerboardPainter {
  paint(ctx, geom, properties) {
    // Use `ctx` as if it was a normal canvas
    const colors = ['red', 'green', 'blue'];
    const size = 32;
    for(let y = 0; y < geom.height/size; y++) {
      for(let x = 0; x < geom.width/size; x++) {
        const color = colors[(x + y) % colors.length];
        ctx.beginPath();
        ctx.fillStyle = color;
        ctx.rect(x * size, y * size, size, size);
        ctx.fill();
      }
    }
  }
}

// Register our class under a specific name
registerPaint('checkerboard', CheckerboardPainter);

如果您過去曾使用 <canvas>,應該對這段程式碼十分熟悉。詳情請見 即時 示範 此處。

以棋盤圖案做為背景圖片的文字區域
以方格圖案圖案做為背景圖片的文字區域。

使用一般背景圖片的差別在於 則會根據使用者調整文字區域的大小,依需求重新繪製。也就是說 背景圖片的大小一律取決於實際大小,包括 則用於高密度螢幕。

很酷,但也很靜態。做法是撰寫新的 每次要使用相同的模式,但大小不同 正方形?答案是不會!

將 Worklet 參數化

幸好,油漆工人可以存取其他 CSS 屬性 新的參數 properties 上架了。為類別提供靜態值 inputProperties 屬性,可用於訂閱任何 CSS 屬性的變更, 包括自訂屬性這些值則會透過 properties 參數。

<!-- index.html -->
<!doctype html>
<style>
  textarea {
    /* The paint worklet subscribes to changes of these custom properties. */
    --checkerboard-spacing: 10;
    --checkerboard-size: 32;
    background-image: paint(checkerboard);
  }
</style>
<textarea></textarea>
<script>
  CSS.paintWorklet.addModule('checkerboard.js');
</script>
// checkerboard.js
class CheckerboardPainter {
  // inputProperties returns a list of CSS properties that this paint function gets access to
  static get inputProperties() { return ['--checkerboard-spacing', '--checkerboard-size']; }

  paint(ctx, geom, properties) {
    // Paint worklet uses CSS Typed OM to model the input values.
    // As of now, they are mostly wrappers around strings,
    // but will be augmented to hold more accessible data over time.
    const size = parseInt(properties.get('--checkerboard-size').toString());
    const spacing = parseInt(properties.get('--checkerboard-spacing').toString());
    const colors = ['red', 'green', 'blue'];
    for(let y = 0; y < geom.height/size; y++) {
      for(let x = 0; x < geom.width/size; x++) {
        ctx.fillStyle = colors[(x + y) % colors.length];
        ctx.beginPath();
        ctx.rect(x*(size + spacing), y*(size + spacing), size, size);
        ctx.fill();
      }
    }
  }
}

registerPaint('checkerboard', CheckerboardPainter);

現在我們就能針對各種不同類型的棋盤使用相同程式碼。但即使 現在可以前往開發人員工具,並填入值 直到找到正確的外觀

瀏覽器不支援油漆工

在本文撰寫期間,只有 Chrome 已實作顏料工作。在那時 都來自所有其他瀏覽器廠商的正向信號,但就沒有什麼進展。 如要掌握最新資訊,請勾選「Houdini Ready Ready 嗎?」, 定期更新資料在此期間,請務必使用漸進式 增強功能,即使不支援繪圖功能,也能持續執行程式碼 Worklet。為確保程式碼能正常運作,您必須調整 CSS 和 JS

您可以透過檢查 CSS 物件,偵測在 JS 中對繪製工作程式的支援: js if ('paintWorklet' in CSS) { CSS.paintWorklet.addModule('mystuff.js'); } CSS 端有兩種選項。您可以使用 @supports

@supports (background: paint(id)) {
  /* ... */
}

有個比較聰明的技巧,就是運用 CSS 無效後 如果其中有不明函式,則會忽略整個屬性宣告。如果 您指定屬性兩次 — 第一個沒有油漆工作組,然後 油漆工人 — 使用漸進式強化功能:

textarea {
  background-image: linear-gradient(0, red, blue);
  background-image: paint(myGradient, red, blue);
}

在「支援」油漆工系的瀏覽器中,第二個宣告 background-image 會覆寫第一個值。使用「不支援」版本的瀏覽器 如果是油漆工作,第二個宣告無效,系統將捨棄該宣告 讓第一個宣告生效

CSS 塗料 Polyfill

很多用途中也可以使用 CSS 顏料 Polyfill、 這項新功能可為新型瀏覽器新增 CSS 自訂繪製和 Paint Worklet。

用途

油漆工件有許多用途 和其他。其中一個較顯而易見的做法 就是運用油漆工人縮小大小 DOM 的組成元素通常,加入元素只會用來製造裝飾 透過 CSS 系統呼叫舉例來說,在 Material Design Lite 中 搭配漣漪效果,包含 2 個額外的 <span> 元素,用於實作 漣漪效果如果有眾多按鈕,這會增加到更多數字 甚至可能導致行動裝置效能降低。如果發生以下情況: 使用顏料塗鴉實作漣漪效果 這時您就會只剩下 0 個元素 只剩下 1 個油漆工 此外,還有比自訂工具更易於自訂的內容 傳遞參數

使用顏料的另一個好處是,在大多數情況下,就是解 繪製工作小程式的處理速度相當小當然, 取捨:只要畫布大小或 參數會變動。因此,如果您的程式碼比較複雜且花費較長時間 卡頓。Chrome 正在努力將油漆工從主執行緒移出 即使是執行時間長的油漆工,也不會影響 。

我認為最令人振奮的潛在客戶是繪畫工作有助於快速上手 為瀏覽器尚未具備的 CSS 功能執行多元填充。例如 來填補錐性梯,直到 登入 Chrome另一個例子:在 CSS 會議中 結果,您現在可以設定多種邊框顏色。本次會議期間 我的同事 Ian Kilpatrick 為這個新的 CSS 撰寫了 polyfill 讓模型瞭解整體行為

跳脫「盒子」的思維框架

大多數人都會從背景圖片和邊框圖片的角度思考 一起來認識油漆工繪製塗鴉更輕鬆簡單 mask-image,讓 DOM 元素具有任意形狀。舉例來說 菱形

鑽石形狀的 DOM 元素。
鑽石形狀的 DOM 元素。

mask-image 會擷取元素大小的圖片。區域 遮罩圖片為透明,元素則為透明。遮罩區域 圖片為不透明,元素不透明。

現已在 Chrome 中

套用小程式的 Chrome Canary 已有一段時間。Chrome 65 讓 預設啟用的功能立即嘗試各種可能 我們打開了上面的彩繪練習球,向我們展示您的創作成果!需要更多靈感 快來看看 Vincent De Oliveira 的系列作品