Let’s implement a fragmented image loading effect today. The effect is as follows:
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