实现一个类似于QQ截图的小东西,点击载入按钮,则载入图片,长按图片,弹出截图框,截图框右下角能够调整大小,并在右边的截图预览区域实时显示
需求
实现一个类似于QQ截图的小东西,点击载入按钮,则载入图片,长按图片,弹出截图框,截图框右下角能够调整大小,并在右边的截图预览区域实时显示,其最终效果图如下:
HTML
需要注意canvas的设置,主要结构如下:
1 2 3 4 5 6 7 8 9
| <section class="clearfix"> <div id="origin"> <canvas id="originImg" width="500" height="500"></canvas> <div id="shotRect"> <div class="resizeBR"></div> </div> </div> <canvas id="showPre" width="500" height="500"></canvas> </section>
|
CSS
截图框初始大小为50px50px,右下角设置了一个不可见的调节区域,此处大小设置为12px12px,并在之后为其注册调整大小的事件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #shotRect { position: absolute; display: none; width: 50px; height: 50px; opacity: .5; border: 2px solid #2d2d2d; }
.resizeBR { position: absolute; right: -5px; bottom: -5px; width: 12px; height: 12px; cursor: nw-resize; opacity: 0; background: #000; background: #ff0; }
|
其中原始图片的canvas大小与预览区的大小一致。
JavaScript
载入图片,并绘制canvas
1 2 3 4 5 6 7 8 9
| function loadImg(event) { cOri = document.getElementById("originImg"); imgOri = new Image(); ctxOri = cOri.getContext("2d"); imgOri.src = "vegetable.jpg"; imgOri.onload=function(){ ctxOri.drawImage(imgOri,0,0,500,500); }; }
|
长按待截图区域,弹出截图框
1 2 3 4 5 6 7 8 9 10 11 12 13
| function longClick(event) { event = event || window.event; var shotRect = document.getElementById("shotRect"); timeout = setTimeout(function() { shotRect.style.display = "block"; var disX = event.clientX - shotRect.offsetWidth + 10, disY = event.clientY - shotRect.offsetHeight + 10; shotRect.style.left = disX + 'px'; shotRect.style.top = disY + 'px'; initCanvas(); updateRect(disX, disY, shotRect.offsetWidth, shotRect.offsetHeight); }, 1000); }
|
释放鼠标时,需要清除timeout。
初始化预览canvas
1 2 3 4 5
| function initCanvas() { cPre = document.getElementById("showPre"); ctxPre = cPre.getContext("2d"); img = document.getElementById("originImg"); }
|
更新预览canvas
根据原始图片,在预览区域上使用drawImage方法画出预览图,其中x,y为截图框左上角相对于原始图片左上角的坐标;而w,h为截图框的长与宽;这四个参数提取出了截图框内的图像数据,而之后(0,0)这个坐标代表在画布上放置该图像数据的坐标位置,(0,0)意味着将该图像数据的左上角与预览区域的左上角重合。
1 2 3 4
| function updateRect(x, y, w, h) { ctxPre.clearRect(0, 0, 500, 500); ctxPre.drawImage(img, x, y, w, h, 0, 0, 500, 500); }
|
调整截图框大小
计算截图框左上角的坐标,并根据调整大小后鼠标的坐标,并据此重新设置截图框的大小,然后调用更新截图预览的函数updateRect,注意限制截图框的边界不能超过原始图片的大小。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| function resizeDown(event) { event = event || window.event; var shotRect = document.getElementById("shotRect"), x = shotRect.offsetLeft, y = shotRect.offsetTop ; document.addEventListener("mousemove", mouseMove); document.addEventListener("mouseup", mouseUp); function mouseMove(event) { event = event || window.event; var finalX = event.clientX, finalY = event.clientY; if (event.clientX >= 488) { finalX = 488; } if (event.clientY >= 488) { finalY = 488; } xy = (finalX - x + 10) < (finalY - y +10) ? (finalX -x + 10) : (finalY - y + 10); shotRect.style.width = xy + 'px'; shotRect.style.height = xy + 'px'; updateRect(x, x, shotRect.offsetWidth, shotRect.offsetHeight); } function mouseUp() { document.removeEventListener("mousemove", mouseMove); document.removeEventListener("mouseup", mouseUp); } }
|
移动截图框
详看注释吧~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| function dragDown(event) { event = event || window.event; if (event.target !== event.currentTarget) return; var shotRect = document.getElementById("shotRect"), disX = event.clientX - shotRect.offsetLeft, disY = event.clientY - shotRect.offsetTop; document.addEventListener("mousemove", mouseMove); document.addEventListener("mouseup", mouseUp);
function mouseMove(event) { event = event || window.event; var disL = event.clientX - disX, disT = event.clientY - disY, maxW = document.getElementById("originImg").clientWidth - shotRect.offsetWidth, maxH = document.getElementById("originImg").clientHeight - shotRect.offsetHeight; if (disL < 0) { disL = 0; } else if (disL > maxW) { disL = maxW + 1; } if (disT < 0) { disT = 0; } else if (disT > maxH) { disT = maxH + 1; } shotRect.style.left = disL + 'px'; shotRect.style.top = disT + 'px'; updateRect(disL, disT, shotRect.offsetWidth, shotRect.offsetHeight); }
function mouseUp(event) { document.removeEventListener("mousemove", mouseMove); document.removeEventListener("mouseup", mouseUp); } }
|
保存图片
由于跨域问题,保存在chrome无效,在firefox中有效:
1 2 3 4 5
| function saveImg(event) { var image = cPre.toDataURL("image/png"); var w = window.open('about:blank', 'image from canvas'); w.document.write("<img src='" + image + "' alt='from canvas'/>"); }
|
完整代码