JS实现网页选取截屏 保存+打印 功能(转)
源码地址:
1.1 确定截图选取范围
用户在开始截图后,需要在页面上选取一个截图范围,并且可以直观的看到,类似如下效果:
我们的选取范围就是鼠标开始按下的那个点到鼠标拖动然后松开的那个点之间所组成的矩形。
为了能直观看到我们选取的范围,我们将这个矩形框随着鼠标拖动给画出来,利用canvas即可,为了方便绘制,这里使用了jcanvas
。
1.2 将选取范围内的网页生成截图
如何将选取框范围内的网页内容变成图像呢,我们可以使用html2canvas.js,html2canvas
可以将页面中的DOM元素生成canvas,是将网页生成图像的非常好的一个选择。使用非常简单:
html2canvas(document.body).then(function(canvas) {
document.body.appendChild(canvas);
});
上面的代码就可以将body
转成canvas。html2canvas
使用到了Promise
,得确保你的浏览器支持。
html2canvas
虽然可以将指定元素转成canvas,有了canvas我们就可以轻易的生成图像。但是并不能满足将选取框范围内的内容转成canvas的需求,选取框内可能有多个元素,并且可能是多个不完整的元素,元素只有部分。
我们可以先将body整个转成canvas,然后将这个canvas进行剪裁(或生成image后剪裁),将选取框范围的内容剪裁出来。很简单,使用drawImage
即可。
drawImage
方法允许在 canvas 中插入其他图像( img 和 canvas 元素) 。drawImage函数有三种函数原型:
drawImage(image, dx, dy)
drawImage(image, dx, dy, dw, dh)
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
2 打印
打印使用 jquery.print.js,jquery.print.js
是一款可以实现网页打印的插件,实用的方法非常简单。类似html2canvas
可以转换元素为canvas这样,它可以选取元素进行部分打印。
$(".print").click(function(){
$(".need_print").print();
});
2 完整实现
创建screenshotsPrint.js
,内容如下:
/**
* 默认画笔线宽
* @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 矩形框的左上角坐标
var canvasLeft = canvasRect.left;
var canvasTop = canvasRect.top; // 要画的矩形的起点 xy
var x = 0;
var y = 0; //鼠标点击按下事件,画图准备
canvas.onmousedown = function(e) { //设置画笔颜色和宽度
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(); //鼠标移动事件,画图
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();
}
};
//鼠标抬起
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转成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);
} /**
* 打印截取区域
* @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) {
// 创建一个用于截取的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')
// 创建一个单击事件
var event = new MouseEvent('click')
// 生成文件名称
var timestamp = new Date().getTime();
var name = imgUrl.substring(22, 30) + timestamp + '.png';
a.download = name
// 将生成的URL设置为a.href属性
a.href = imgUrl;
// 触发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="来个跨区的图片">
</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('现在你可以使用鼠标拖拽选取打印区域,松开后完成')
//调用选取截屏
clipScreenshots("bg_canvas");
}); });
</script>
</body>
</html>
作者:石文文的简书
链接:https://www.jianshu.com/p/8c43576bdbe3
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
JS实现网页选取截屏 保存+打印 功能(转)的更多相关文章
- js利用clipboardData在网页中实现截屏粘贴的功能
目前仅有高版本的 Chrome 浏览器支持这样直接粘贴,其他浏览器目前为止还无法粘贴,不过火狐和ie11浏览器在可编辑的div中能够粘贴截图的图片也是base64位和Chrome利用clipboard ...
- 利用 clipboardData 在网页中实现截屏粘贴的功能
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- android截屏:保存一个view的内容为图片并存放到SD卡
项目中偶尔会用到截屏分享,于是就有了下面这个截屏的方法~ 下面得saveImage()方法就是保存当前Activity对应的屏幕所有内容的截屏保存. private void saveImage() ...
- iOS截屏保存至相册
#pragma mark 截屏并保存至相册 -(void)screenShotsComplete:(void(^)(UIImage * img)) complete { CGSize imageSiz ...
- Unity3d 截屏保存到相册,并且刷新相册
要做一个截图的功能,并且玩家可以在相册中看到. 做的时候遇到了三个问题: 1.unity自带的截图API,Application.CaptureScreenshot在Android上不生效 2.图片保 ...
- IOS 截屏(保存到相册中)
@interface NJViewController () /** * 点击截屏按钮 */ - (IBAction)captureView:(UIButton *)sender; /** * 白色v ...
- js 将网页生成为html保存访问
2012-04-03 今天实现了一个需求,主题是将浏览中的网页生成html保存起来,记录访问url,挂在公司网站上做案例. 首先忙活了N久的是去搜索生成html的js函数. 什么IE自带的 ...
- 使用adb命令对手机进行截屏保存到电脑,SDCard
adb shell /system/bin/screencap -p /sdcard/screenshot.png(保存到SDCard) adb pull /sdcard/screenshot.png ...
- vba截屏保存
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVa ...
随机推荐
- Python CGI编程Ⅲ
GET和POST方法 浏览器客户端通过两种方法向服务器传递https://www.xuanhe.net/信息,这两种方法就是 GET 方法和 POST 方法. 使用GET方法传输数据 GET方法发送编 ...
- kubernetes运用
1:kubernetes基本介绍 kubernetes 是一个开源的容器集群管理系统,K8s用于容器化应用程序的部署 扩展和管理,提供容器编排 资源调度 弹性伸缩 部署管理 服务发现等一系列功能. ...
- 利用jquery 实现菜单控制对应视图的显示与隐藏
效果: <!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta ...
- @ApiParam和@RequestHeader接收参数的区别
一.代码 @ApiOperation(value = "查询学生信息") @GetMapping(value = "/select/student") @Api ...
- 2018 计蒜之道-初赛 第一场 A-百度无人车
百度一共制造了 nn 辆无人车,其中第 ii 辆车的重量为 a_i\ \mathrm{kg}ai kg. 由于车辆过重会增大轮胎的磨损程度,现在要给这 nn 辆车减轻重量.每将一辆车减轻 1\ \m ...
- Fiona简介
Fiona是一个python地理空间处理库,类似于OGR
- 分享几个免费IP地址查询接口(API)
淘宝IP地址库 提供的服务包括:1. 根据用户提供的IP地址,快速查询出该IP地址所在的地理信息和地理相关的信息,包括国家.省.市和运营商.2. 用户可以根据自己所在的位置和使用的IP地址更新我们的服 ...
- python爬取智联招聘职位信息(多进程)
测试了下,采用单进程爬取5000条数据大概需要22分钟,速度太慢了点.我们把脚本改进下,采用多进程. 首先获取所有要爬取的URL,在这里不建议使用集合,字典或列表的数据类型来保存这些URL,因为数据量 ...
- 一、基础篇--1.1Java基础-equals与==的区别
==: ==比较的是变量内存中存放的对象的内存地址,用来判断两个对象地址是否相同,比较的是否是同一个对象. 1.两边的操作数必须是同一类型,不然编译不通过. 2.如果是基本数据类型比较,值相等则为tr ...
- UVa679 小球下落(树)
UVa679 小球下落(树) 题目大意 小球从一棵所有叶子深度相同的二叉树的顶点开始向下落,树开始所有节点都为0.若小球落到节点为0的则往左落,否则向右落.并且小球会改变它经过的节点,0变1,1变0. ...