HTML部分
<body>
<div
class="wrap"
onmousedown="handleMouseDown(event)"
onmousemove="handleMouseMove(event)"
onmouseup="handleMouseUp(event)"
>
<img id="image" src="" alt="" />
<canvas
style="left: 30px;top: 40px;"
width="300"
height="200"
id="canvas"
></canvas>
</div>
<input type="file" onchange="handleInput(event)" />
<button onclick="handleCut()">截取</button>
<button onclick="handleDownload()">下载</button>
</body>
CSS部分
.wrap {
width: 600px;
height: 400px;
position: relative;
border: 1px solid #333;
box-sizing: border-box;
}
#image {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
#canvas {
position: absolute;
border: 1px solid rgb(136, 219, 119);
background: rgba(156, 156, 156, 0.3);
display: none;
z-index: 100;
box-sizing: border-box;
}
button {
width: 80px;
height: 30px;
}
JS部分
let imageFile = null;
let isMouseDown = false;
let wrap = document.getElementsByClassName("wrap")[0];
let ctx = document.getElementById("canvas");
let img = document.getElementById("image");
let content = ctx.getContext("2d");
let wrapWidth = wrap.offsetWidth;
let wrapHeight = wrap.offsetHeight;
let ctxWidth, ctxHeight;
function handleInput(e) {
imageFile = e.target.files[0];
let fileReader = new FileReader();
fileReader.onload = function(e) {
img.src = e.target.result;
canvas.style.display = "block";
ctxWidth = ctx.offsetWidth;
ctxHeight = ctx.offsetHeight;
};
// 将文件转化为base64编码
fileReader.readAsDataURL(imageFile);
}
function handleMouseDown(event) {
if (!img.getAttribute("src")) return;
// 一旦移动位置,就清空画布
ctx.height = ctx.height;
isMouseDown = true;
updateSite(event.pageX, event.pageY);
}
function handleMouseMove(event) {
if (!isMouseDown) return;
updateSite(event.pageX, event.pageY);
}
function handleMouseUp(event) {
isMouseDown = false;
}
// 移动canvas位置
function updateSite(X, Y) {
let currentTop, currentLeft;
if (Y + ctxHeight / 2 >= wrapHeight) {
currentTop = wrapHeight - ctxHeight;
} else if (Y - ctxHeight / 2 <= 0) {
currentTop = 0;
} else {
currentTop = Y - ctxHeight / 2;
console.log("currentTop", currentTop, Y - ctxHeight / 2, ctxHeight);
}
if (X + ctxWidth / 2 >= wrapWidth) {
currentLeft = wrapWidth - ctxWidth;
} else if (X - ctxWidth / 2 <= 0) {
currentLeft = 0;
} else {
currentLeft = X - ctxWidth / 2;
console.log("currentLeft", currentLeft, X - ctxWidth / 2, ctxWidth);
}
ctx.style.top = currentTop + "px";
ctx.style.left = currentLeft + "px";
}
// 截取
function handleCut(type = "image/png") {
if (!img.getAttribute("src")) {
alert("请导入图片");
return;
}
let cutImg = document.createElement("img");
content.drawImage(
img,
-parseInt(ctx.style.left),
-parseInt(ctx.style.top),
wrap.scrollWidth,
wrap.scrollHeight
);
cutImg.src = ctx.toDataURL(type);
document.body.append(cutImg);
}
function handleDownload() {
if (!img.getAttribute("src")) {
alert("请导入图片");
return;
}
loadFile(DataURLToFile(ctx.toDataURL()));
}
function DataURLToFile(dataUrl, filename = "file", type) {
let arr = dataUrl.split(",");
let bstr = atob(arr[1]);
!type && (type = arr[0].replace("data:", "").replace(";base64", ""));
let n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type });
}
// 下载文件
function loadFile(content, filename = "file") {
var aLink = document.createElement("a");
aLink.download = filename;
aLink.href = URL.createObjectURL(content);
aLink.click();
URL.revokeObjectURL(content);
}
效果如下,截取框内的图片,并可通过下载按钮下载