1. ホーム
  2. Web制作
  3. HTML/Xhtml

HTMLコードによる画像断片化読み込み機能

2022-01-07 16:26:57

今日はこんな感じの断片化された画像の読み込み効果を実装します。

これを3つのステップで行っています。

  • htmlの構造を定義する
  • 画像の分割
  • アニメーション関数の作成

htmlの構造を定義する

ここで必要なのは、canvas要素だけです。

<html>
  <body>
    <canvas
      id="myCanvas"
      width="900"
      height="600"
      style="background-color: black;"
    ></canvas>
  </body>
</html>

画像の分割

この例では、画像を10行10列のグリッドに100個の小片に分割し、それぞれの小片を独立してレンダリングできるようにしています。

let image = new Image();
image.src = "https://cdn.yinhengli.com/canvas-example.jpeg";
let boxWidth, boxHeight;
// split into 10 rows and 10 columns
let rows = 10,
  columns = 20,
  counter = 0;

image.onload = function () {
  // Calculate the width and height of each row and column
  boxWidth = image.width / columns;
  boxHeight = image.height / rows;
  // Render in a loop
  requestAnimationFrame(animate);
};

requestAnimationFrame : アニメーションを実行することをブラウザに伝え、次の再描画の前にアニメーションを更新するために、指定されたコールバック関数を呼び出すようブラウザに依頼します。

アニメーション関数の書き方

次に、各リペイントの前にブラウザがランダムに小さな断片をレンダリングするためのアニメーション関数を書きます。

ここで肝心なのは、context.drawImageメソッドです。

let canvas = document.getElementById("myCanvas");
let context = canvas.getContext("2d");

function animate() {
  // Render a random module
  let x = Math.floor(Math.random() * columns);
  let y = Math.floor(Math.random() * rows);
  // Core
  context.drawImage(
    image,
    x * boxWidth, // the starting position of the horizontal coordinate in the canvas
    y * boxHeight, // the starting position of the vertical coordinate in the canvas
    boxWidth, // the width of the drawing (the width of the small fragment image)
    boxHeight, // the height of the drawing (height of the image of the fragment)
    x * boxWidth, // start drawing from the x coordinate position of the large image
    y * boxHeight, // draw from the y-coordinate position of the big picture
    boxWidth, // how wide to draw from the x position of the larger image (the width of the small fragment image)
    boxHeight // from the y position of the big picture, how high (the height of the small fragment image)
  );
  counter++;
  // If the module renders 90% of the image, let the whole image be displayed.
  if (counter > columns * rows * 0.9) {
    context.drawImage(image, 0, 0);
  } else {
    requestAnimationFrame(animate);
  }
}

フルコード

<html>
  <body>
    <canvas
      id="myCanvas"
      width="900"
      height="600"
      style="background-color: black;"
    ></canvas>
    <script>
      let image = new Image();
      image.src = "https://cdn.yinhengli.com/canvas-example.jpeg";
      let canvas = document.getElementById("myCanvas");
      let context = canvas.getContext("2d");
      let boxWidth, boxHeight;
      let rows = 10,
        columns = 20,
        counter = 0;

      image.onload = function () {
        boxWidth = image.width / columns;
        boxHeight = image.height / rows;
        requestAnimationFrame(animate);
      };

      function animate() {
        let x = Math.floor(Math.random() * columns);
        let y = Math.floor(Math.random() * rows);
        context.drawImage(
          image,
          x * boxWidth, // the starting position of the horizontal coordinate
          y * boxHeight, // the starting position of the vertical coordinate
          boxWidth, // the width of the image
          boxHeight, // the height of the image
          x * boxWidth, // the x-coordinate position on the canvas where the image is placed
          y * boxHeight, // the y-coordinate position on the canvas where the image will be placed
          boxWidth, // the width of the image to be used
          boxHeight // the height of the image to be used
        );
        counter++;
        if (counter > columns * rows * 0.9) {
          context.drawImage(image, 0, 0);
        } else {
          requestAnimationFrame(animate);
        }
      }
    </script>
  </body>
</html>

概要

このデモでは、canvasAPI を使用して断片化された画像の読み込み効果を実現しました。

HTMLコードによる画像断片化読み込みの記事はこちらです。もっと関連するHTML画像断片化読み込みのコンテンツは、スクリプトハウスの過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後ともスクリプトハウスをよろしくお願いします