js网页截图(JS如何实现页面截屏功能实例代码)
js网页截图
JS如何实现页面截屏功能实例代码"页面截屏"是前端经常遇到的需求,比如页面生成海报,弹窗图片分享等,因为浏览器没有原生的截图API,所以需要借助canvas来实现导出图片实现需求。
可行性方案
- 方案1: 将 DOM 改写成 canvas ,调用canvas的toBlob或者toDataURL方法即刻上传到七牛云或服务器
- 方案2: 使用第三方库html2canvas.js实现 canvas , 在不更改页面已有DOM的情况下优雅生产canvas
解决方案的选择
方案1:需要手动计算每个DOM元素的Computed Style,然后需要计算好元素在canvas的大小位置等属性。
方案1难点
- 需要弃用已有的html页面,改用canvas重写。
- 页面结构层复杂的情况下用canvas写,不易重构。
- 有一定canvas基础。
方案2:该项目在Github上stars已有两万多start,作者仍在积极维护。API非常简单,在已有项目中开箱即用。
html2canvas
因为是常见的需求,所以社区会有成熟的解决方案,首先试试社区的解决方案。
<li id="capture" style="padding: 10px; background: #f5da55"> <h4 style="color: #000; ">Hello world!</h4> </li>
html2canvas(document.querySelector("#capture")).then(canvas => { document.body.appendChild(canvas) });
以上是官网的实例用法。在网页上出现了一个新的 canvas DOM。接下来我们只需要把canvas转换成图片就好。这里使用canva原生的toDataURL和toBlob方法上次到七牛云。
使用时需要注意。此处如果生产的画布中有跨域图片,需要配置allowTaint为true。
如果是原生canvas实现,canvas需要所有跨域图片请求完成才可绘制。有两种解决方案
- 方案1:在html上写好img标签,src写好对应的图片url。缺点很明显,会污染页面的布局结构。
- 方案2:使用js,使用new Image()的方式。设置src到对应的图片url,在onload回调中处理相关操作。优点:可行性最高,不过有回调地狱的问题。我们用Promise改写一下
function asyncImage(url) { const img = new Image(); img.src = url; img.setAttribute('crossOrigin', 'anonymous'); return new Promise((resolve, reject) => { img.onload = () => resolve(img); img.onerror = reject; }); }
好的,大功告成~是不是可以交付需求了呢?开开心心提测,但是在移动端测试的时候发现生产的图片非常模糊。这样是不行的,明显low了许多(测试不给过orz)。
github有相应的解决方案 传送门 ,这个回答也是解决很多人的问题
基本原理:将canvas宽高放大两倍。把css把canvas的style设置成1倍大小。
var shareContent = YourTargetElem; var width = shareContent.offsetWidth; var height = shareContent.offsetHeight; var canvas = document.createElement("canvas"); var scale = 2 || window.devicePixelRatio ; //也可以使用设备像素比 canvas.width = width * scale; canvas.height = height * scale; canvas.getContext("2d").scale(scale, scale); var opts = { scale: scale, canvas: canvas, logging: true, width: width, height: height }; html2canvas(shareContent, opts).then(function (canvas) { var context = canvas.getContext('2d'); var img = Canvas2Image.convertToImage(canvas, canvas.width, canvas.height); document.body.appendChild(img); $(img).css({ "width": canvas.width / 2 + "px", "height": canvas.height / 2 + "px", }) });
原理我们已经知道了,实际操作之后图像也确实清晰了很多。但是问题还是没有解决掉。
缩小虽然提高了清晰度,但是我们需要的图片是原始比例的大小。。
最终多次尝试无果后,选择放弃使用框架。直接用原生canvas撸一个!
canvas绘制
我们知道,在高清屏的设备下,任何绘制canvas中的图像、文字、线条、形状都可能会出现模糊的问题。可通过引入 GitHub 中的 hidpi-canvas 有效地解决。
- 首先去 GitHub 下载 hidpi-canvas.js 文件:传送门;
- 在项目中引入 hidpi-canvas.js 文件;
- 调用 getPixelRatio() 函数,得到 ratio 值;
- 在 drawImage() 中,将 width 和 height 乘以 ratio;
- 最终的canvas导出为Blog,转换成文件对象上传七牛云。
核心代码如下
function asyncImage(url) { const img = new Image(); img.src = url; img.setAttribute('crossOrigin', 'anonymous'); return new Promise((resolve, reject) => { img.onload = () => resolve(img); img.onerror = reject; }); } async function drawCanvas(){ var canvas = document.querySelector('canvas'); var context = canvas.getContext('2d'); var ratio = getPixelRatio(context); // 关键代码 canvas.width = 300 * ratio; // 画布宽度 canvas.height = 300 * ratio; // 画布高度 var liWidth = 300 * ratio; // 用于内容居中 var liHeight = 300 * ratio; // 用于内容居中 const image = await asyncImage('picUrl') const imgWidth = 550 const imgHeight = 300 context.drawImage(this, 50, 50, imgWidth * ratio, imgHeight * ratio) // Some other code const Blob = canvas.toBlob((Blob)=>{ //上传七牛云 }); }
最终生成的图片终于清晰了...只需要根据dom的offsetWidth等适配不同屏幕就可以了。
总结
如果对图片的清晰度要求不高,或者图片需求是生成缩略图的情况下。采用 html2canvas 是非常不错的选择。
否则,还是用canvas绘制出的图片更清晰。
到此这篇关于JS如何实现页面截屏功能的文章就介绍到这了,更多相关JS页面截屏功能内容请搜索开心学习网以前的文章或继续浏览下面的相关文章希望大家以后多多支持开心学习网!
- extjs checkboxGroup 复选框的用法
- php加密平台(PHP7实现和CryptoJS的AES加密方式互通示例AES-128-ECB加密)
- js实现自动轮播(原生js封装无缝轮播功能)
- js 原生事件代理(如何利用原生JS实现触摸滑动监听事件)
- js定时器几分钟执行(利用JS定时器实现元素移动)
- js浮点数运算精度问题(JS超出精度数字问题的解决方法)
- 用js编写tab栏切换(JavaScript实现简易tab栏切换内容栏)
- js中什么是宏任务(浅谈JavaScript宏任务和微任务执行顺序)
- js如何操作json字符串
- js闭包可以解决哪些问题(JavaScript中let避免闭包造成问题)
- javascript写游戏脚本(原生JS实现飞机大战小游戏)
- php抽奖功能(php+lottery.js实现九宫格抽奖功能)
- js中事件的三个阶段(JavaScript中事件冒泡机制示例详析)
- js数字时钟编程(JavaScript实现动态数字时钟)
- js淘宝购物车效果代码(JavaScript实现电商平台商品细节图)
- JS中instanceof与typeof的区别有哪些
- 富士胶片 中国 我们对上海的信心没有任何改变(富士胶片中国)
- 赢麻了 富士公布2021年度财报 营利同比增长240(富士公布2021年度财报)
- 医事文化谈屑 | 古人的名 字 号(医事文化谈屑古人的名)
- ()
- 网友很惭愧,自己写了很多年的字,到头来还不如一名小学生写的好(自己写了很多年的字)
- 中华第一楷 张瑞龄 86岁高龄,苦练楷书71年,一幅字卖593万(中华第一楷张瑞龄)
热门推荐
- angular怎么创建声明(使用Angular CDK实现一个Service弹出Toast组件功能)
- 阿里云服务器内外网址(阿里云服务器网站发现后门该怎么处理)
- sql server设置标识列(Sql Server 如何去掉内容里面的Html标签)
- vue图片组件使用方法(Vue图片裁剪组件实例代码)
- Ext.MessageBox.show()的用法及参数配置
- dedecms系统参数设置(织梦dedecms首页调用指定栏目内容的标签详解)
- 云服务器有必要买吗(云服务器好用吗?云服务器值得买吗?)
- docker-compose启动超时(docker compose idea CreateProcess error=2 系统找不到指定的文件的问题)
- filezilla搭建ftp服务器英文(客户端使用FileZilla连接ftp服务器过程图解)
- 深入理解php 变量(不常用但很实用的PHP预定义变量分析)