CSSペイントAPIを使用して、解像度に依存しない可変背景効果を動的に作成します。

CSSペイントAPIを使用して、解像度に依存しない可変背景効果を動的に作成します。

出典: https://medium.com/better-programming、著者: Ferenc Almasi

最近の Web アプリケーションは画像が多く、ネットワーク経由でダウンロードされるバイトの大部分を占めています。最適化することで、パフォーマンスをより有効に活用できます。背景画像として幾何学的形状を使用する場合は、別の方法があります。CSSペイントAPI [1]を使用してプログラムで背景を生成することができます。

このチュートリアルでは、その機能について説明し、解像度に依存しない動的な背景を動的に作成するためにどのように使用できるかについて説明します。このチュートリアルの出力は次のようになります。

参考: CSS ペイント API の概要

プロジェクトの設定

まず、新しいindex.htmlファイルを作成し、次のコードを記述します。

<!DOCTYPE html>
<html lang="ja">
  <ヘッド>
    <メタ文字セット="UTF-8" />
    <meta name="viewport" content="width=デバイス幅、初期スケール=1.0" />
    <title>:art: CSS ペイント API</title>
    <link rel="スタイルシート" href="styles.css" />
  </head>
  <本文>
    <テキストエリアクラス="パターン"></テキストエリア>
    <スクリプト>
      if (CSS の 'paintWorklet') {
        CSS.paintWorklet.addModule('pattern.js');
      }
    </スクリプト>
  </本文>
</html>

注意すべき点がいくつかあります:

  • 13 行目では、新しい Paint ワークレットを読み込みます。現在、世界全体の支持率は約63%です。したがって、まずpaintWorkletがサポートされているかどうかを確認する必要があります。
  • キャンバスのサイズを変更するとパターンがどのように再描画されるかを確認できるように、デモンストレーションにtextareaを使用しています。
  • 最後に、 pattern.js (ペイントワークスペースを登録するため) と、いくつかのスタイルを定義できるstyles.cssを作成する必要があります。

ワークレットとは何ですか?

ペイント ワークレットは、キャンバスに何を描画するかを定義するクラスです。これらはcanvas要素と同様に動作します。この分野について以前に知識がある場合、コードは馴染みのあるものになるはずです。ただし、100% 同一というわけではありません。たとえば、テキスト レンダリング メソッドはワークレットではまだサポートされていません。

ここで、CSS スタイルも定義します。ここでワークレットを使用します。

。パターン {
  幅: 250ピクセル;
  高さ: 250px;
  境界線: 1px実線 #000;

  背景画像: ペイント(パターン);
}

textareaがよく見えるように黒い枠線を追加しました。ペイント ワークレットを参照するには、 paint(worklet-name)値としてbackground-imageプロパティに渡します。しかし、 patternどこから来るのでしょうか?まだ定義していないので、次のステップとして定義してみましょう。

ワークレットの定義

pattern.jsを開き、以下を追加します。

クラスパターン{
  ペイント(コンテキスト、キャンバス、プロパティ) {

  }
}

ペイントを登録します('パターン', パターン);

ここで、 registerPaintメソッドを使用してpaintWorklet登録できます。ここで定義された CSS の最初のパラメータを参照できます。 2 番目のパラメーターは、キャンバスに何を描画するかを定義するクラスです。 3 つのパラメータを取るpaintメソッドがあります。

コンテクスト
ペイントレンダリングコンテキスト2D
キャンバスレンダリングコンテキスト2D API

canvas : これはキャンバスであり、幅と高さの 2 つのプロパティのみを持つPaintSizeオブジェクトです。

properties : これは、JavaScript 経由で CSS プロパティとその値を読み取るために使用できるStylePropertyMapReadOnlyオブジェクトを返します。

長方形を描く

次のステップは何かを表示することですので、四角形を描きましょう。 paintメソッドに次のコードを追加します。

ペイント(コンテキスト、キャンバス、プロパティ) {
  (let x = 0; x < canvas.height / 20; x++) {
    (y = 0; y < canvas.width / 20; y++) の場合 {
      const bgColor = (x + y) % 2 === 0 ? '#FFF' : '#FFCC00';

      コンテキスト.shadowColor = '#212121';
      コンテキスト.shadowBlur = 10;
      コンテキスト.shadowOffsetX = 10;
      コンテキスト.shadowOffsetY = 1;

      コンテキスト.beginPath();
      コンテキストの塗りつぶしスタイル = bgColor;
      コンテキスト.rect(x * 20, y * 20, 20, 20);
      コンテキストを埋め込む();
    }
  }
}

ここで行ったことは、キャンバスの幅と高さをループするネストされたループを作成することだけです。長方形のサイズは 20 なので、長方形の高さと幅を 20 で割ります。

4 行目では、モジュラス演算子を使用して 2 つの色を切り替えることができます。深みを出すために影も追加しました。最後に、キャンバス上に長方形を描きます。ブラウザで開くと、次のような画面が表示されます。

背景をダイナミックにする

残念ながら、 textareaサイズ変更と、Paint API がすべてのものを再描画する方法を覗く以外は、これはほとんど静的です。そこで、変更可能なカスタム CSS プロパティを追加して、もう少し動的な操作を行えるようにしてみましょう。

styles.cssを開き、次の行を追加します。

。パターン {
     幅: 250ピクセル;
     高さ: 250px;
     境界線: 1px実線 #000;

     背景画像: ペイント(パターン);
+ --パターンカラー: #FFCC00;
+ --パターンサイズ: 23;
+ --パターン間隔: 0;
+ --パターンシャドウぼかし: 10;
+ --パターンシャドウx: 10;
+ --パターンシャドウy: 1;
 }

をプレフィックスとして付けると、カスタム CSS プロパティを定義できます。これらのプロパティはvar()関数で使用できます。しかし、私たちの場合は、ペイントワークレットでそれを使用します。

CSS のサポートを確認する

Paint API がサポートされていることを確認するには、CSS でのサポートも確認します。これを行うには、2 つのオプションがあります。

  • ルールを守るには@supportsルールを使用します。
  • フォールバック背景画像を使用します。
/* 最初のオプション */
@supports (背景: ペイント(パターン)) {
  /**
   * このセクションが評価された場合、Paint API がサポートされていることを意味します**/
}

/**
 * 2 番目のオプション * Paint API がサポートされている場合、後者のルールが最初のルールを上書きします。
 * サポートされていない場合は、CSS によって無効とみなされ、url() のルールが適用されます。
 **/
。パターン {
  背景画像: url(pattern.png);
  背景画像: ペイント(パターン);
}

ペイントワークレットのパラメータにアクセスする

pattern.jsでこれらのパラメータを読み取るには、ペイント ワークレットを定義するクラスに新しいメソッドを追加する必要があります。

クラスパターン{
  // `inputProperties` メソッドによって返されるものはすべてペイント ワークレットからアクセスできます。
  静的に入力プロパティを取得します(){
    戻る [
      '--パターンカラー',
      '--パターンサイズ',
      '--パターン間隔',
      '--パターンシャドウぼかし',
      '--パターンシャドウx',
      '--パターンシャドウ-y'
    ];
  }
}

paintメソッド内でこれらのプロパティにアクセスするには、 properties.getを使用します。

ペイント(コンテキスト、キャンバス、プロパティ) {
  定数プロパティ = {
    色: properties.get('--pattern-color').toString().trim(),
    サイズ: parseInt(properties.get('--pattern-size').toString()),
    間隔: parseInt(properties.get('--pattern-spacing').toString()),
    影の多い:
      ぼかし: parseInt(properties.get('--pattern-shadow-blur').toString()),
      x: parseInt(properties.get('--pattern-shadow-x').toString()),
      y: parseInt(properties.get('--pattern-shadow-y').toString())
    }
  };
}

色については、文字列に変換する必要があります。その他はすべて数値に変換する必要があります。これは、 properties.getCSSUnparsedValueを返すためです。

properties.get の戻り値

読みやすくするために、解析を処理する 2 つの新しい関数を作成しました。

ペイント(コンテキスト、キャンバス、プロパティ) {
  const getPropertyAsString = プロパティ => properties.get(property).toString().trim();
  const getPropertyAsNumber = プロパティ => parseInt(properties.get(property).toString());

  定数プロパティ = {
    色: getPropertyAsString('--pattern-color'),
    サイズ: getPropertyAsNumber('--pattern-size'),
    間隔: getPropertyAsNumber('--pattern-spacing'),
    影の多い:
      ぼかし: getPropertyAsNumber('--pattern-shadow-blur'),
      x: getPropertyAsNumber('--pattern-shadow-x'),
      y: getPropertyAsNumber('--pattern-shadow-y')
    }
  };
}

ここで必要なのは、 for ループ内のすべてを対応するprop値に置き換えることだけです。

(let x = 0; x < canvas.height / props.size; x++) {
  (y = 0; y < canvas.width / props.size; y++) の場合 {
    const bgColor = (x + y) % 2 === 0 ? '#FFF' : props.color;

    コンテキスト.shadowColor = '#212121';
    context.shadowBlur = props.shadow.blur;
    コンテキストの影オフセットX = props.shadow.x;
    コンテキストの影オフセットY = props.shadow.y;

    コンテキスト.beginPath();
    コンテキストの塗りつぶしスタイル = bgColor;
    context.rect(x * (props.size + props.spacing),
                 y * (props.size + props.spacing)、props.size、props.size);
    コンテキストを埋め込む();
  }
}

ブラウザに戻って変更してみてください。

DevToolsで背景概要を編集する

CSS ペイント API が便利なのはなぜでしょうか?ユースケースは何ですか?

最も明白なことは、応答のサイズが縮小されることです。画像の使用を排除することで、ネットワーク リクエストと数千バイトを節約できます。これによりパフォーマンスが向上します。

DOM 要素を使用する複雑な CSS 効果の場合は、ページ上のノードの数を減らすこともできます。 Paint API を使用すると複雑なアニメーションを作成できるため、追加の空ノードは必要ありません。

私の意見では、最大の利点は、静的な背景画像よりもはるかにカスタマイズ性に優れていることです。 API を使用すると、解像度に依存しない画像を作成することもできるため、単一の画面サイズが欠けることを心配する必要がありません。

現在 CSS Paint API を使用する場合は、まだ広く採用されていないため、必ずポリフィルを提供してください。完成したプロジェクトを微調整したい場合は、このGitHubリポジトリ[2]からクローンすることができます。

グリーンブックの公式バージョン: 最初の 2 つのバージョンの蓄積と 3 年間の包括的な書き直しを経て、この本はついにテクニカル分析とユーザー エクスペリエンスの完璧な一致を実現しました。

広さと深さが素晴らしい記事になっています。深さの点では、この本は世界でも比類のない JS の背後にある理由を掘り下げています。広さの点では、この本はセマンティクスの詳細を取り上げており、これを読んだ後、メカニズムについて混乱することはなくなります。

スーパー言語の考え方:すべてのものは同じ目的を持ち、類似しています。JS シェルを剥ぎ取ると、この本が言語の技術的な本質を高レベルから分析し、すべてのプログラミング言語に適用できることがわかります。

育成の鍵は再学習です。ハイブリッド アプリ、ノード サーバー、FaaS、クラウド ネイティブ、フロントエンド インテリジェンスの時代において、本質に戻ってこの基本コースを再度受講すると、さらに速く進むことができます。

参考文献[1]

CSS ペイント API: https://developer.mozilla.org/en-US/docs/Web/API/CSS_Painting_API

[2]

GitHub リポジトリ: https://github.com/flowforfrank/css-paint

CSS ペイント API を使用して解像度に依存しない可変背景効果を動的に作成する方法についての説明はこれで終わりです。CSS ペイント API 可変背景に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

<<:  Vue はトークンを取得してトークン ログインのサンプル コードを実装します

>>:  2つのシンプルなメニューナビゲーションバーの例

推薦する

CSSは座席選択効果を実現するためにautoflow属性を使用する

1. 自動フロー属性、要素コンテンツの長さと幅が要素自体の長さと幅を超える場合、スクロールバーが表示...

Dockerを使用して分散lnmpイメージを作成する

目次1. Docker分散lnmpイメージ生成1. Nginx、MySQL、PHPコンテナを実行する...

VMware Workstation 14 Pro(仮想マシン)にシステムをインストールする方法の詳細な説明

この記事では、VMware Workstation 14 Pro (仮想マシン) にシステムをインス...

HTML におけるベースタグの使用に関する詳細な説明

requireJS には、baseURL というプロパティがあります。baseURL を設定すること...

SQL インジェクションの詳細

1. SQL インジェクションとは何ですか? SQL インジェクションは、入力パラメータに SQL ...

Vue2 と Vue3 でウォッチ リスナーを使用する方法

watch : データの変更を監視する(特定の値の変更イベント) vue2.x データ(){ 戻る ...

「いいね!」機能では MySQL と Redis のどちらを使用すればよいでしょうか?

目次1. 初心者が陥りがちな間違い2. Iteratorのremove()メソッドを使用する3. f...

Webpack4プラグインの実装原理についての簡単な説明

目次序文知る練習すれば完璧になる序文wabpack では、ローダーの他にプラグインがコア機能です。プ...

クールな花火効果を実現するjs

この記事では、jsを使用してクールな花火効果を実現するための具体的なコードを参考までに共有します。具...

sqlite3 から mysql に移行するときに起こりうる問題のコレクション

簡単な説明適切な読者: モバイル開発sqlite3 データを mysql に移行する場合、多くの構文...

Linux/Mac MySQL パスワードを忘れた場合の対処方法

Linux/Mac の MySQL パスワードを忘れた場合はどうすればいいですか?心配しないでくださ...

JavaScript で Baidu Maps API にアクセスする方法と手順

目次1. Baidu Map API アクセス2. HTML で Baidu Map API を使用...

チェックボックスとラジオボタンの配置を実装する方法

ブラウザによって動作が異なるだけでなく、フォントやテキスト サイズによっても動作が異なります。フォー...

JavaScript でドラッグ スライダー パズルの検証機能を実装します (html5、canvas)

導入:スライダー ドラッグ検証は現在、多くの場所で使用されています。週末に 1 つ作成しようと思い、...

Vue3 の ref toRef と toRefs の違いを理解する方法

目次1. 基本1.参照2. 参照3. 参照4. 最適な使い方2. 詳細な1. なぜrefが必要なのか...