CSS Paint API

Chrome 65 の新たな可能性

CSS Paint API(別名: CSS Custom Paint、Houdini のペイント ワークレット)は、 デフォルトで有効になっています。概要: 対処方法 どうすればよいでしょうか。その仕組みじゃあ、続けて読めよ...

CSS Paint API を使用すると、CSS によって常に画像が生成され、 画像が必要です。background-imageborder-image などのプロパティ 通常は、画像ファイルを読み込むために url() とともに使用するか、CSS 組み込みとともに使用します。 linear-gradient() のような関数を使用できます。これらを使用する代わりに paint(myPainter): ペイント ワークレットを参照します。

ペイント ワークレットの作成

myPainter というペイント ワークレットを定義するには、CSS ペイントを読み込む必要があります。 CSS.paintWorklet.addModule('my-paint-worklet.js') を使用したワークレット ファイル。その registerPaint 関数を使用して、ペイント ワークレット クラスを登録できます。

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> を使用したことがある方は、このコードに見覚えがあるでしょう。詳しくは、 ライブ デモ 見てみましょう。

背景画像としてチェッカーボード パターンを使用したテキストエリア
背景画像としてチェッカーボード パターンを使用したテキストエリア。

一般的な背景画像を使用する場合との違いは、 ユーザーがテキスト領域のサイズを変更するとオンデマンドで再描画されるようになります。つまり 背景画像は 補正しています。

素晴らしいですが、静的でもあります。新しいルールを 同じパターンでサイズが異なるときに毎回ワークレットを 正方形?答えはノーです。

ワークレットをパラメータ化する

幸いなことに、ペイント ワークレットは他の 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);

これで、すべての異なる種類のチェッカーボードに同じコードを使用できるようになりました。しかし、 よくなったので、DevTools で値をいじることができます。 正しい結果が得られるまで

ペイント ワークレットをサポートしていないブラウザ

執筆時点では、Chrome にのみペイント ワークレットが実装されています。移動中 他のすべてのブラウザ ベンダーから肯定的な兆候であり、あまり進展はありません。 最新情報については、Is Houdini Ready Yet? をご覧ください。 定期的に確認しましょう。それまでの間は、プログレッシブ ペイントがサポートされていなくてもコードを実行し続けることができる、 ワークレットです想定どおりに動作させるには、Terraform でコードを調整する必要があります。 CSS と JS の 2 つの場所に配置されます

JS でのペイント ワークレットのサポートを検出するには、CSS オブジェクトを確認します。 js if ('paintWorklet' in CSS) { CSS.paintWorklet.addModule('mystuff.js'); } CSS 側では、2 つの選択肢があります。@supports を使用できます。

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

より簡潔な方法は、CSS によって無効化され、その後に は、プロパティの宣言に不明な関数が含まれている場合、プロパティ宣言全体を無視します。条件 プロパティは 2 回指定します。1 回目はペイント ワークレットなし、2 回目は ペイント ワークレット — プログレッシブ エンハンスメント:

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

ペイント ワークレットをサポートするブラウザでは、 background-image によって最初のものが上書きされます。非対応のブラウザの場合 ペイント ワークレットの場合、2 番目の宣言は無効であり、破棄されます。 最初の宣言が有効になります。

CSS ペイント ポリフィル

多くの用途では、Terraform を使用して CSS ペイント ポリフィル では、最新のブラウザに CSS カスタム ペイントとペイント ワークレットのサポートが追加されます。

ユースケース

ペイント ワークレットのユースケースは数多くあり、その中には できます。もっとわかりやすいのは、ペイント ワークレットを使用してサイズを小さくすることです。 できます。多くの場合、装飾を施すためだけに要素が追加される 作成しますたとえば、Material Design Lite では、このボタンは 波紋効果のある 2 つの <span> 要素で、 波及していきますボタンの数が多い場合、ボタンの数も増える可能性があります。 要素が多く、モバイルでのパフォーマンスの低下につながることがあります。もし ペイント ワークレットを使用して波紋効果を実装する 追加要素が 0 で、ペイント ワークレットが 1 つだけになります。 さらに カスタマイズも簡単で パラメータ化します。

ペイント ワークレットを使用するもう一つの利点は、ほとんどの場合、 ペイント ワークレットを使用した場合は、バイト数が小さいという結果になります。もちろん、 描画コードはキャンバスのサイズまたは パラメータの変更だけです。そのため コードが複雑で時間がかかると できます。Chrome は、ペイント ワークレットをメインスレッドから移動して、 長時間実行されるペイント ワークレットでも、メインのコンテナの応答性に 使用します。

私にとって最も興味を引かれたのは、ペイント ワークレットによって ブラウザがまだ用意していない CSS 機能をポリフィルできます。たとえば 円錐グラデーションをポリフィルします。 Chrome にネイティブに実装されます別の例を挙げます。CSS の会議では、 枠線を複数色に設定できるようになりました。この会議が まだ進行中です。同僚の Ian Kilpatrick がこの新しい CSS のポリフィルを作成しました ペイント ワークレットを使用します。

既成概念にとらわれずに考える

ほとんどの人は背景画像や枠線の画像は、 ペイント ワークレットについて学びます。ペイント ワークレットの直感的ではないユースケースの一つに、 mask-image: DOM 要素の形状を任意のものにします。たとえば、 diamond:

<ph type="x-smartling-placeholder">
</ph> ひし形の形の DOM 要素。 <ph type="x-smartling-placeholder">
</ph> ひし形の形の DOM 要素。

mask-image は、要素のサイズの画像を受け取ります。倫理上の問題を引き起こす マスク画像は透明で、要素は透明です。マスクがある領域 画像は不透明で、要素は不透明です。

Chrome で利用可能に

ペイント ワークレットは以前から Chrome Canary で使用されていました。Chrome 65 では、 デフォルトで有効になっています。新たな可能性をぜひお試しください ペイント ワークレットが開き、作成したものをお見せします。ヒントとして Vincent De Oliveira のコレクションをご覧ください。