使用JS實現(xiàn)網(wǎng)頁中類似QQ截圖的效果,并將截圖打印或者保存腮郊。這是幫朋友解決的一個小需求轧飞,跟大家分享一下。體驗地址:測試截取打印保存
1. JS網(wǎng)頁選取截屏實現(xiàn)思路
1.1 確定截圖選取范圍
用戶在開始截圖后大渤,需要在頁面上選取一個截圖范圍掸绞,并且可以直觀的看到衔掸,類似如下效果:
我們的選取范圍就是鼠標(biāo)開始按下的那個點到鼠標(biāo)拖動然后松開的那個點之間所組成的矩形敞映。
為了能直觀看到我們選取的范圍,我們將這個矩形框隨著鼠標(biāo)拖動給畫出來捷犹,利用canvas即可冕末,為了方便繪制档桃,這里使用了
jcanvas
。
1.2 將選取范圍內(nèi)的網(wǎng)頁生成截圖
如何將選取框范圍內(nèi)的網(wǎng)頁內(nèi)容變成圖像呢销凑,我們可以使用html2canvas.js仅炊,html2canvas
可以將頁面中的DOM元素生成canvas抚垄,是將網(wǎng)頁生成圖像的非常好的一個選擇。使用非常簡單:
html2canvas(document.body).then(function(canvas) {
document.body.appendChild(canvas);
});
上面的代碼就可以將body
轉(zhuǎn)成canvas桐经。html2canvas
使用到了Promise
阴挣,得確保你的瀏覽器支持纺腊。
html2canvas
雖然可以將指定元素轉(zhuǎn)成canvas茎芭,有了canvas我們就可以輕易的生成圖像梅桩。但是并不能滿足將選取框范圍內(nèi)的內(nèi)容轉(zhuǎn)成canvas的需求拜隧,選取框內(nèi)可能有多個元素洪添,并且可能是多個不完整的元素,元素只有部分外臂。
我們可以先將body整個轉(zhuǎn)成canvas律胀,然后將這個canvas進行剪裁(或生成image后剪裁)炭菌,將選取框范圍的內(nèi)容剪裁出來。很簡單赘艳,使用drawImage
即可蕾管。
drawImage
方法允許在 canvas 中插入其他圖像( img 和 canvas 元素) 菩暗。drawImage函數(shù)有三種函數(shù)原型:
drawImage(image, dx, dy)
drawImage(image, dx, dy, dw, dh)
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
其中image可以是canvas停团,image,video三種元素秒梅。
參數(shù) | 描述 |
---|---|
image | 要使用的圖像舌胶、畫布或視頻 |
sx 可選 | 開始剪切的 x 坐標(biāo)位置 |
sy 可選 | 開始剪切的 y 坐標(biāo)位置 |
sw 可選 | 被剪切圖像的寬度 |
sh 可選 | 被剪切圖像的高度 |
dx | 在畫布上放置圖像的 x 坐標(biāo)位置 |
dy | 在畫布上放置圖像的 y 坐標(biāo)位置 |
dw 可選 | 要使用的圖像的寬度 |
dh 可選 | 要使用的圖像的高度 |
2 打印
打印使用 jquery.print.js ,jquery.print.js
是一款可以實現(xiàn)網(wǎng)頁打印的插件誊薄,實用的方法非常簡單娩井。類似html2canvas
可以轉(zhuǎn)換元素為canvas這樣洞辣,它可以選取元素進行部分打印昙衅。
$(".print").click(function(){
$(".need_print").print();
});
2 完整實現(xiàn)
創(chuàng)建screenshotsPrint.js
,內(nèi)容如下:
/**
* 默認(rèn)畫筆線寬
* @type {number}
*/
var defaultStrokeWidth = 1; //畫矩形選取框的線寬
/**
* 選取劃線的canvasExt
* @type {{drawRect: canvasExt.drawRect}}
*/
var canvasExt = {
/**
* 畫矩形
* @param canvasId canvasId
* @param penColor 畫筆顏色
* @param strokeWidth 線寬
*/
drawRect: function (canvasId, penColor, strokeWidth) {
var that = this;
that.penColor = penColor;
that.penWidth = strokeWidth;
var canvas = document.getElementById(canvasId);
//canvas 的矩形框
var canvasRect = canvas.getBoundingClientRect();
//canvas 矩形框的左上角坐標(biāo)
var canvasLeft = canvasRect.left;
var canvasTop = canvasRect.top;
// 要畫的矩形的起點 xy
var x = 0;
var y = 0;
//鼠標(biāo)點擊按下事件著瓶,畫圖準(zhǔn)備
canvas.onmousedown = function(e) {
//設(shè)置畫筆顏色和寬度
var color = that.penColor;
var penWidth = that.penWidth;
// 確定起點
x = e.clientX - canvasLeft;
y = e.clientY - canvasTop;
// 添加layer
$("#"+canvasId).addLayer({
type: 'rectangle',
strokeStyle: color,
strokeWidth: penWidth,
name:'areaLayer',
fromCenter: false,
x: x, y: y,
width: 1,
height: 1
});
// 繪制
$("#"+canvasId).drawLayers();
$("#"+canvasId).saveCanvas();
//鼠標(biāo)移動事件材原,畫圖
canvas.onmousemove = function(e){
// 要畫的矩形的寬高
var width = e.clientX-canvasLeft - x;
var height = e.clientY-canvasTop - y;
// 清除之前畫的
$("#"+canvasId).removeLayer('areaLayer');
$("#"+canvasId).addLayer({
type: 'rectangle',
strokeStyle: color,
strokeWidth: penWidth,
name:'areaLayer',
fromCenter: false,
x: x, y: y,
width: width,
height: height
});
$("#"+canvasId).drawLayers();
}
};
//鼠標(biāo)抬起
canvas.onmouseup=function(e){
var color = that.penColor;
var penWidth = that.penWidth;
canvas.onmousemove = null;
var width = e.clientX - canvasLeft - x;
var height = e.clientY- canvasTop - y;
$("#"+canvasId).removeLayer('areaLayer');
$("#"+canvasId).addLayer({
type: 'rectangle',
strokeStyle: color,
strokeWidth: penWidth,
name:'areaLayer',
fromCenter: false,
x: x, y: y,
width: width,
height: height
});
$("#"+canvasId).drawLayers();
$("#"+canvasId).saveCanvas();
// 把body轉(zhuǎn)成canvas
html2canvas(document.body, {
scale: 1,
// allowTaint: true,
useCORS: true //跨域使用
}).then(canvas => {
var capture_x, capture_y
if (width > 0) {
//從左往右畫
capture_x = x + that.penWidth
}else {
//從右往左畫
capture_x = x + width + that.penWidth
}
if (height > 0) {
//從上往下畫
capture_y = y + that.penWidth
}else {
//從下往上畫
capture_y = y + height + that.penWidth
}
printClip(canvas, capture_x, capture_y, Math.abs(width), Math.abs(height))
});
// 移除畫的選取框
$("#"+canvasId).removeLayer('areaLayer');
// 隱藏用于華畫取框的canvas
$("#"+canvasId).hide()
}
}
};
/**
* 選取截屏
* @param canvasId
*/
function clipScreenshots(canvasId){
canvasExt.drawRect(canvasId, "red", defaultStrokeWidth);
}
/**
* 打印截取區(qū)域
* @param canvas 截取的canvas
* @param capture_x 截取的起點x
* @param capture_y 截取的起點y
* @param capture_width 截取的起點寬
* @param capture_height 截取的起點高
*/
function printClip(canvas, capture_x, capture_y, capture_width, capture_height) {
// 創(chuàng)建一個用于截取的canvas
var clipCanvas = document.createElement('canvas')
clipCanvas.width = capture_width
clipCanvas.height = capture_height
// 截取
clipCanvas.getContext('2d').drawImage(canvas, capture_x, capture_y, capture_width, capture_height, 0, 0, capture_width, capture_height)
var clipImgBase64 = clipCanvas.toDataURL()
// 生成圖片
var clipImg = new Image()
clipImg.src = clipImgBase64
var con = confirm('打印截圖嗎?取消則保存截圖')
if (con) {
$(clipImg).print()
}else {
downloadIamge(clipImgBase64)
}
}
/**
* 下載保存圖片
* @param imgUrl 圖片地址
*/
function downloadIamge(imgUrl) {
// 圖片保存有很多方式,這里使用了一種投機的簡單方法威酒。
// 生成一個a元素
var a = document.createElement('a')
// 創(chuàng)建一個單擊事件
var event = new MouseEvent('click')
// 生成文件名稱
var timestamp = new Date().getTime();
var name = imgUrl.substring(22, 30) + timestamp + '.png';
a.download = name
// 將生成的URL設(shè)置為a.href屬性
a.href = imgUrl;
// 觸發(fā)a的單擊事件 開始下載
a.dispatchEvent(event);
}
在demo.html
中進行使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>測試截取保存或打印</title>
<script type="text/javascript" src="libs/jquery-2.1.0.js"></script>
<script type="text/javascript" src="libs/html2canvas.js"></script>
<script type="text/javascript" src="libs/jQuery.print.js"></script>
<script type="text/javascript" src="libs/jcanvas.min.js"></script>
<script type="text/javascript" src="js/screenshotsPrint.js"></script>
<style>
body, html {
width: 100%;
height: 100%;
}
.print {
position: relative;
z-index: 100;
}
h1 {
color: orangered;
}
h2 {
color: darkblue;
}
h2 {
color: forestgreen;
}
#bg_canvas {
position: absolute;
z-index: 500;
left: 0;
top: 0;
}
</style>
</head>
<body>
<button class="print">開始截圖</button>
<div>
<h1>哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈</h1>
<h2>嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿嘿</h2>
<h3>呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵</h3>
<br/>
<p>這是一張跨域圖片</p>
<img src="http://p7.qhimg.com/t01ceede0272d4b5a8b.png" alt="來個跨區(qū)的圖片">
</div>
<!-- 用于畫選取框的canvas -->
<canvas id="bg_canvas" width="100%" height="100%" />
<script>
$(function(){
var clientWidth = document.documentElement.clientWidth || document.body.clientWidth
var clientHeight = document.documentElement.clientHeight || document.body.clientHeight
// 更新canvas寬高
$("#bg_canvas").attr("width", clientWidth);
$("#bg_canvas").attr("height", clientHeight);
$("#bg_canvas").hide();
$(".print").click(function(){
$("#bg_canvas").show()
alert('現(xiàn)在你可以使用鼠標(biāo)拖拽選取打印區(qū)域,松開后完成')
//調(diào)用選取截屏
clipScreenshots("bg_canvas");
});
});
</script>
</body>
</html>
演示地址: 測試截取打印保存
源碼地址: web_screenshots_print