Two lines of code to achieve fragmented loading of images

Let’s implement a fragmented image loading effect today. The effect is as follows:

Fragmented loading

We are divided into 3 steps to achieve:

  • Define html structure

  • Split picture

  • Writing animation functions

Define html structure

Only one canvas element is needed here.

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

Split picture

In this example, we split the image into 100 small fragments according to a grid of 10 rows and 10 columns, so that each small fragment can be rendered independently.

let image = new Image();
image.src = "https://cdn.yinhengli.com/canvas-example.jpeg";
let boxWidth, boxHeight;
// 拆分成 10 行,10 列
let rows = 10,
  columns = 20,
  counter = 0;

image.onload = function () {
  // 计算每一行,每一列的宽高
  boxWidth = image.width / columns;
  boxHeight = image.height / rows;
  // 循环渲染
  requestAnimationFrame(animate);
};

requestAnimationFrame: Tell the browser that you want to perform an animation, and ask the browser to call the specified callback function to update the animation before the next redraw.

Writing animation functions

Next, we write an animation function to allow the browser to randomly render a small fragment before each redraw.

The core here is the context.drawImage method.

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

function animate() {
  // 随机渲染某个模块
  let x = Math.floor(Math.random() * columns);
  let y = Math.floor(Math.random() * rows);
  // 核心
  context.drawImage(
    image,
    x * boxWidth,  // canvas 中横坐标起始位置
    y * boxHeight, // canvas 中纵坐标起始位置
    boxWidth,      // 画图的宽度(小碎片图像的宽)
    boxHeight,     // 画图的高度(小碎片图像的高)
    x * boxWidth,  // 从大图的 x 坐标位置开始画图
    y * boxHeight, // 从大图的 y 坐标位置开始画图
    boxWidth,      // 从大图的 x 位置开始,画多宽(小碎片图像的宽)
    boxHeight      // 从大图的 y 位置开始,画多高(小碎片图像的高)
  );
  counter++;
  // 如果模块渲染了 90%,就让整个图片显示出来。
  if (counter > columns * rows * 0.9) {
    context.drawImage(image, 0, 0);
  } else {
    requestAnimationFrame(animate);
  }
}

Complete code

<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, // 横坐标起始位置
          y * boxHeight, // 纵坐标起始位置
          boxWidth, // 图像的宽
          boxHeight, // 图像的高
          x * boxWidth, // 在画布上放置图像的 x 坐标位置
          y * boxHeight, // 在画布上放置图像的 y 坐标位置
          boxWidth, // 要使用的图像的宽度
          boxHeight // 要使用的图像的高度
        );
        counter++;
        if (counter > columns * rows * 0.9) {
          context.drawImage(image, 0, 0);
        } else {
          requestAnimationFrame(animate);
        }
      }
    </script>
  </body>
</html>

to sum up

Through this demo, we used canvasAPI to achieve the effect of loading fragments of pictures, isn't it particularly simple!

"Watching and forwarding" is the greatest support

Guess you like

Origin blog.csdn.net/liuyan19891230/article/details/108162441