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つのシンプルなメニューナビゲーションバーの例

推薦する

リソースアップロード機能を実現するための SpringBoot+nginx の詳細な例

最近、画像、ビデオ、CSS/JS などの静的リソースを配置するために nginx を使用する方法を学...

Puppeteer を使用して Linux (CentOS) で Web ページのスクリーンショット機能を実装する

Linux に puppeteer をインストールするときに、次の問題が発生する可能性があります。こ...

Vueは小さなメモ帳機能を実装しました

この記事の例では、メモ帳の小さな機能を実現するためのvueの具体的なコードを参考までに共有しています...

Linux 7.7 でスワップ パーティション SWAP を設定する方法

Linux システムの Swap パーティション、つまり swap パーティションは、一般に仮想メモ...

HTML ウェブページハイパーリンクタグ

HTML ウェブ ページのハイパーリンク タグの学習チュートリアル リンク タグの属性 リンクは、ウ...

js Promise同時制御メソッド

目次質問背景アイデアと実装質問次のように、同時実行 Promise の数を制御するメソッドを記述する...

CSS カウンターとコンテンツの概要

コンテンツ プロパティは CSS 2.1 で導入され、:before および :after 疑似要素...

ミニプログラムカスタムタブバーコンポーネントのカプセル化

この記事の例では、ミニプログラムのカスタムタブバーコンポーネントをカプセル化するための具体的なコード...

CSS スタッキングと Z インデックスのサンプルコード

カスケードとカスケードレベルHTML 要素は 3 次元の概念です。水平方向と垂直方向に加えて、「Z ...

Hyper-v仮想マシンを使用してCentos7をインストールする

目次導入準備するシステムイメージをダウンロードHyper-Vを有効にする新しい仮想ネットワークスイッ...

Nodejs でモジュール fs ファイルシステムを使用する方法

目次概要ファイル記述子同期、非同期、Promise同期書き込み非同期書き込み(推奨)約束​​の書き方...

CSS カウンターを使用して数字の順序付きリストを美しく表示する方法

Web デザインでは、Web サイトに表示されるデータの構造とコンテンツをユーザーが明確に理解できる...

DockerのTLS(SSL)証明書の有効期限の問題を解決する

問題現象: [root@localhost ~]# docker イメージをプル xxx.com.c...

Nginx で HTTPS 証明書を構成する詳細なプロセス

1. HttpとHttpsの違いHTTP: インターネットで最も広く使用されているネットワーク プロ...

HTMLリンクタグのrel属性

<link> タグは、現在のドキュメントと Web コレクション内の他のドキュメントとの...