html5实现图片分割主要依赖canvas元素的绘图能力,通过加载目标图片后,按照预设的行列数切割成多个小块,再将每个小块绘制到对应的位置即可完成效果。整个流程不需要依赖第三方库,原生html5和javascript就能实现。

实现原理说明
核心思路是先创建一个canvas画布作为绘图容器,加载需要分割的图片资源,然后根据设定的行数和列数,计算每个小块的宽度和高度。接着使用drawImage方法的带参数重载形式,从原图片中截取对应区域的内容,绘制到新的位置或者新的canvas上,最终得到分割后的多个图片块。
基础实现步骤
1. 搭建基础页面结构
首先需要在页面中创建canvas元素,以及用于展示分割后结果的容器,同时准备需要分割的图片资源。注意这里提到的<canvas>是html5的绘图标签,不需要额外引入其他资源。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>html5图片分割示例</title>
<style>
.container {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 20px;
}
.piece {
border: 1px solid #ccc;
}
</style>
</head>
<body>
<!-- 原图片 -->
<img id="sourceImg" src="https://ipipp.com/sample.jpg" alt="原图" style="max-width: 400px;">
<!-- 绘图用的canvas,默认隐藏 -->
<canvas id="drawCanvas" style="display: none;"></canvas>
<!-- 分割结果容器 -->
<div class="container" id="resultContainer"></div>
<script src="split.js"></script>
</body>
</html>
2. 编写图片分割核心逻辑
在javascript文件中,首先获取页面元素,监听原图片的加载完成事件,避免图片未加载完成就进行切割导致错误。然后计算每个碎片的尺寸,循环截取原图片的对应区域,生成新的图片块并插入到结果容器中。
// 获取页面元素
const sourceImg = document.getElementById('sourceImg');
const drawCanvas = document.getElementById('drawCanvas');
const resultContainer = document.getElementById('resultContainer');
const ctx = drawCanvas.getContext('2d');
// 分割参数:行数和列数
const row = 3;
const col = 3;
// 监听原图片加载完成
sourceImg.onload = function() {
// 设置canvas尺寸和原图片一致
const imgWidth = sourceImg.width;
const imgHeight = sourceImg.height;
drawCanvas.width = imgWidth;
drawCanvas.height = imgHeight;
// 计算每个小块的宽高
const pieceWidth = imgWidth / col;
const pieceHeight = imgHeight / row;
// 循环切割图片
for (let i = 0; i < row; i++) {
for (let j = 0; j < col; j++) {
// 清空canvas
ctx.clearRect(0, 0, imgWidth, imgHeight);
// 截取原图片的对应区域
// drawImage参数:图片资源, 截取起始x, 截取起始y, 截取宽度, 截取高度, 绘制起始x, 绘制起始y, 绘制宽度, 绘制高度
ctx.drawImage(
sourceImg,
j * pieceWidth, // 截取起始x坐标
i * pieceHeight, // 截取起始y坐标
pieceWidth, // 截取宽度
pieceHeight, // 截取高度
0, // 绘制到canvas的起始x
0, // 绘制到canvas的起始y
pieceWidth, // 绘制宽度
pieceHeight // 绘制高度
);
// 将canvas内容转为图片
const pieceImg = new Image();
pieceImg.src = drawCanvas.toDataURL('image/png');
pieceImg.className = 'piece';
pieceImg.style.width = pieceWidth + 'px';
pieceImg.style.height = pieceHeight + 'px';
// 添加自定义属性记录碎片位置
pieceImg.dataset.row = i;
pieceImg.dataset.col = j;
// 插入结果容器
resultContainer.appendChild(pieceImg);
}
}
};
// 处理图片加载失败的情况
sourceImg.onerror = function() {
alert('图片加载失败,请检查图片地址是否正确');
};
关键方法说明
整个实现中最重要的就是drawImage方法的9参数重载形式,参数含义如下:
| 参数位置 | 参数含义 |
|---|---|
| 1 | 要绘制的图片资源,可以是img元素、canvas元素或者video元素 |
| 2 | 从原图片中截取的起始x坐标 |
| 3 | 从原图片中截取的起始y坐标 |
| 4 | 截取的宽度 |
| 5 | 截取的高度 |
| 6 | 绘制到目标canvas的起始x坐标 |
| 7 | 绘制到目标canvas的起始y坐标 |
| 8 | 绘制到canvas的宽度,可缩放图片 |
| 9 | 绘制到canvas的高度,可缩放图片 |
扩展优化方向
- 可以调整row和col参数,实现任意行列数的图片分割,比如2行4列、4行4列等
- 可以给分割后的图片块添加拖拽事件,实现拼图游戏的基础功能
- 可以修改绘制逻辑,给每个碎片添加边框、阴影等样式,提升视觉效果
- 如果需要将分割后的图片保存到本地,可以给每个碎片图片添加下载按钮,调用
download属性实现下载
注意事项
如果图片资源是跨域加载的,调用toDataURL方法时会触发安全错误,此时需要给图片添加crossorigin="anonymous"属性,并且确保图片所在的服务器允许跨域访问。
另外计算碎片尺寸时,如果原图片的宽高不能整除行列数,可能会出现边缘碎片尺寸偏差的问题,此时可以调整计算逻辑,让最后一个行或者列的碎片使用剩余尺寸,保证所有碎片拼接后能还原原图片。