代码如下:
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>H5 canvas绘制框选截图和保存截图代码</title>
<style>
*{padding:0;margin:0;}
#drawImgBox {position:relative;margin:100px auto;width:1000px;}
#drawImgBox .box {position:relative;width: 435px; height:600px;}
#drawImgBox .box img{position:absolute; left:0;width: 435px; height:600px;user-select:none;}
#drawImgBox canvas{background: #eee;position:relative;z-index:99999;display:none;}
#drawImgBox #selectRect {background:#3385ff;opacity:0.55;border:1px solid blue;position:absolute;}
#drawImgBox .btn {width:435px;padding:20px 0; text-align:center;}
</style>
</head>
<body>
<div id="drawImgBox">
<div class="box">
<img src="./demo.png" draggable="false"/>
<canvas width="435" height="600" style="display:none;"></canvas>
</div>
<div class="btn">
<button class="preview">预览截图</button>
<button class="download-img">下载图片</button>
</div>
</div>
<script>
(function (){
let startX, // 鼠标按下相对页面X的坐标
startY, // 鼠标按下相对页面Y的坐标
endX, // 鼠标松开相对页面X的坐标
endY, // 鼠标松开相对页面Y的坐标
dragWidth, // 选择框的宽度
dragHeight, // 选择框的高度
dragLeft, // 选择框的相对box左边的距离
dragTop; // 选择框的相对box上边的距离
let flag = false; // 鼠标按下标识
let selectRect = null;
let preview = document.querySelector('#drawImgBox .preview');
let download = document.querySelector('#drawImgBox .download-img');
let box = document.querySelector('#drawImgBox .box');
let canvas = document.querySelector('#drawImgBox canvas');
let content = canvas.getContext('2d');
// 获取元素到页面左边或者上边的距离
function getElementPosition (el) {
var actualTop = el.offsetTop;
var actualLeft = el.offsetLeft;
var current = el.offsetParent;
while (current !== null) {
actualTop += current.offsetTop;
actualLeft += current.offsetLeft;
current = current.offsetParent;
}
return {top:actualTop, left: actualLeft};
}
// 下载按钮
download.onclick = function () {
let imgBase64 = canvas.toDataURL("image/png"); //获取截图base64, 1表示质量(无损压缩)
let a = document.createElement('a');
a.download = '截取图片.png'; // 必须要设置download属性才能够直接下载base64图片
a.href = imgBase64;
a.click(); // 触发点击,起到下载效果
};
// 预览按钮
preview.onclick = function () {
if (canvas.style.display === 'none') {
canvas.style.display = 'block';
this.innerText = '取消预览';
} else {
canvas.style.display = 'none';
this.innerText = '预览截图';
}
};
// 鼠标按下
box.onmousedown = function (e) {
startX = e.pageX;
startY = e.pageY;
// 获取外层box元素相对页面的偏移量
let drawImgBox = document.querySelector('#drawImgBox');
let elOffsetLeft = getElementPosition(drawImgBox).left;
let elOffsetTop = getElementPosition(drawImgBox).top;
flag = true;
// 绘制选中框效果
selectRect = document.createElement('div');
selectRect.id = 'selectRect';
selectRect.style.display = 'none';
// 设置选中框的left和top值,注意要减去元素相对页面的left,top偏移量才可以得出正确效果
selectRect.style.left = (startX - elOffsetLeft) + 'px';
selectRect.style.top = (startY - elOffsetTop) + 'px';
// 赋值选中框相对图片的偏移量用户后面截图
dragLeft = (startX - elOffsetLeft);
dragTop = (startY - elOffsetTop);
this.appendChild(selectRect);
};
// 鼠标移动绘制选中框效果
box.onmousemove = function (e) {
if (flag) {
let X = e.pageX;
let Y = e.pageY;
let cwidth = null;
let cheight = null;
let width = X - startX;
let height = Y - startY;
selectRect.style.display = 'block';
// 计算绘制框的宽和高
if (width > 0) {
cwidth = width;
cheight = height;
} else {
cwidth = -width;
cheight = -height;
}
dragWidth = cwidth;
dragHeight = cheight;
// 设置选择框的宽和高
document.querySelector('#drawImgBox .box #selectRect').style.width = cwidth + 'px';
document.querySelector('#drawImgBox .box #selectRect').style.height = cheight + 'px';
}
};
box.onmouseup = function (e) {
flag = false;
canvas.height = canvas.height; // 重置画布宽高可以清空画布;
let img = new Image();
img.src = './demo.png';
img.crossOrigin = 'Anonymous';
// 绘制图片到canvas
content.drawImage(img, dragLeft, dragTop, dragWidth, dragHeight, 0, 0, dragWidth, dragHeight);
// 重置变量标识
startX = 0;
startY = 0;
endX = 0;
endY = 0;
dragWidth = 0;
dragHeight = 0;
dragLeft = 0;
dragTop = 0;
document.querySelector('#drawImgBox #selectRect') && document.querySelector('#drawImgBox .box').removeChild(document.querySelector('#drawImgBox #selectRect'));
};
})();
</script>
</body>
</html>