<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>canvas实现截图功能</title><style>.canvas-box,.canvas2-box{display: none;}</style>
</head>
<body><!-- 文件读取 --><div><input type="file" id="file" accept="image/*" /></div><canvas id="canvas-node" class="canvas-box"></canvas><button id="downBtn">down</button><div class="canvas2-box"><canvas id="canvas2"></canvas></div>
</body>
<script>// 获取canvas节点let canvasNode = document.getElementById("canvas-node")// 创建上下文let ctx = canvasNode.getContext("2d")let downBtn = document.getElementById("downBtn")let canvas2Box = document.querySelector(".canvas2-box")let canvas2 = document.getElementById("canvas2")let ctx2 = canvas2.getContext("2d")// 获取文件节点let fileNode = document.getElementById("file")// 给文件节点注册事件fileNode.addEventListener("change", readFile)// 图像源let img = new Image();// 截图区域的数据let screenshotData = []let fileType = "" // 文件的类型,下载的时候需要// 注册事件用于得到鼠标按下时的偏移量canvasNode.addEventListener("mousedown", mousedownInCanvasHandler)let currentPoint = {}// 注册下载事件downBtn.addEventListener('click',()=>{let {width, height} = canvas2// format:表示的是图片的类型 "image/png"// toDataURL的第一个参数:图片格式,默认为 image/png,// 第2个参数:可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。let imgURL = canvas2.toDataURL( fileType, 1);let link = document.createElement('a');link.download = "截图图片";link.href = imgURL;document.body.appendChild(link);link.click();document.body.removeChild(link);})// 鼠标按下function mousedownInCanvasHandler(e){currentPoint= { x: e.offsetX, y: e.offsetY }// 按下鼠标的时候我们需要注册移动事件和抬起事件canvasNode.addEventListener('mousemove', mousemoveInCanvasHandler)canvasNode.addEventListener('mouseup', mouseupInCanvasHandler)}// 绘制矩形function mousemoveInCanvasHandler(e){let rectEndX = e.offsetXlet rectEndY = e.offsetY// 得到矩形的宽度和高度let rectWidth = rectEndX - currentPoint.xlet rectHeight = rectEndY - currentPoint.ylet {width, height} = canvasNode// 将截图区域的数据保存下来screenshotData= [currentPoint.x, currentPoint.y, rectWidth, rectHeight]ctx.clearRect(0, 0, width, height)// 绘制蒙层drawMask(0,0,width, height);drawScreenShot(width, height,rectWidth, rectHeight)}// 绘制截图function drawScreenShot( canvasWidth, canvasHeight,rectWidth,rectHeight){// 在原图形之外画出一个矩形ctx.globalCompositeOperation = "destination-out";ctx.fillStyle='#000'ctx.fillRect(currentPoint.x, currentPoint.y,rectWidth,rectHeight)ctx.globalCompositeOperation ='destination-over'// 绘制截图区域的矩形ctx.drawImage(img, 0, 0,canvasWidth, canvasHeight,0,0,canvasWidth, canvasHeight );}// 鼠标抬起的时候要移除移动事件和抬起事件function mouseupInCanvasHandler(e){canvasNode.removeEventListener('mousemove', mousemoveInCanvasHandler)canvasNode.removeEventListener('mouseup', mouseupInCanvasHandler)drawScreenShotImg(screenshotData)}// 绘制一个截图区域的信息在另外一个画布上,并且将他显示出来function drawScreenShotImg(screenshotData){// screenshotData是截图的开始和结束坐标let drawData = ctx.getImageData(...screenshotData)canvasSetWH(canvas2Box,screenshotData[2],screenshotData[3])canvasSetWH(canvas2,screenshotData[2],screenshotData[3])// 先清空画布,注意清空的大小,否者会造成叠加(清除不干净)ctx2.clearRect(0,0, currentPoint.x, currentPoint.y)// 将截图区域绘制到canvas2上ctx2.putImageData(drawData,0,0)}// 读取文件function readFile(e){let file = e.target.files[0]// 得到图片的类型,等会下载的时候需要console.log('file.type', file.type)fileType = file.typegetImageWH(file, function(width, height) { // 将宽度和高度传给canvasSetWH函数,显示在页面上canvasSetWH(canvasNode,width, height)ctx.drawImage(img, 0, 0,width, height );// 调用绘制蒙层的方法drawMask(0,0,width, height);});}// 返回文件(图片的宽和高)function getImageWH(file, callback) { // 创建一个FileReader实例 const reader = new FileReader(); // 当文件读取完成时触发 reader.onload = function(e) { // e 这个对象中包含这个图片相关的属性console.log('e这个对象', e)// 创建一个新的Image对象 // 设置Image的src为读取到的文件内容 img.src = e.target.result; // 当图片加载时触发 img.onload = function() { // 调用回调函数,返回图像源,图片的宽度,高度callback(img.width, img.height); };};// 开始读取文件内容,以DataURL的形式 // reader.onload 方法的执行需要调用下面这个 reader.readAsDataURLreader.readAsDataURL(file); } function canvasSetWH(canvasNode,width, height){canvasNode.width = widthcanvasNode.height = heightcanvasNode.style.display = "block"}// 绘制蒙层function drawMask(x, y, width, height, opactity) {ctx.fillStyle = "rgba(0,0,0,0.5)";ctx.fillRect(x, y, width, height);}
</script>
</html>