JS如何实现页⾯截屏功能实例代码
"页⾯截屏"是前端经常遇到的需求,⽐如页⾯⽣成海报,弹窗图⽚分享等,因为浏览器没有原⽣的截图API,所以需要借助canvas来实现导出图⽚实现需求。
可⾏性⽅案
1. ⽅案1:将 DOM 改写成 canvas ,调⽤canvas的toBlob或者toDataURL⽅法即刻上传到七⽜云或服务器
2. ⽅案2:使⽤第三⽅库html2canvas.js实现 canvas ,在不更改页⾯已有DOM的情况下优雅⽣产canvas
解决⽅案的选择
⽅案1:需要⼿动计算每个DOM元素的Computed Style,然后需要计算好元素在canvas的⼤⼩位置等属性。
⽅案1难点
需要弃⽤已有的html页⾯,改⽤canvas重写。
页⾯结构层复杂的情况下⽤canvas写,不易重构。
有⼀定canvas基础。
⽅案2:该项⽬在Github上stars已有两万多start,作者仍在积极维护。API⾮常简单,在已有项⽬中开箱即⽤。
html2canvas
因为是常见的需求,所以社区会有成熟的解决⽅案,⾸先试试社区的解决⽅案。
<div id="capture" >
<h4 >Hello world!</h4>
</div>
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) => {
});
}
好的,⼤功告成~是不是可以交付需求了呢?开开⼼⼼提测,但是在移动端测试的时候发现⽣产的图⽚⾮常模糊。这样是不⾏的,明显low了许多(测试不给过orz)。
github有相应的解决⽅案,这个回答也是解决很多⼈的问题
基本原理:将canvas宽⾼放⼤两倍。把css把canvas的style设置成1倍⼤⼩。
var shareContent = YourTargetElem;
var width = shareContent.offsetWidth;
var height = shareContent.offsetHeight;
var canvas = ateElement("canvas");
var scale = 2 || window.devicePixelRatio ; //也可以使⽤设备像素⽐
canvas.width = width * scale;
canvas.height = height * scale;
var opts = {
scale: scale,
canvas: canvas,
logging: true,
width: width,
height: height
};
html2canvas(shareContent, opts).then(function (canvas) {
var context = Context('2d');
var img = vertToImage(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 有效地解决。
1. ⾸先去 GitHub 下载 hidpi-canvas.js ⽂件:传送门;
2. 在项⽬中引⼊ hidpi-canvas.js ⽂件;
3. 调⽤ getPixelRatio() 函数,得到 ratio 值;
4. 在 drawImage() 中,将 width 和 height 乘以 ratio;
5. 最终的canvas导出为Blog,转换成⽂件对象上传七⽜云。
核⼼代码如下
function asyncImage(url) {
const img = new Image();
img.src = url;
img.setAttribute('crossOrigin', 'anonymous');
return new Promise((resolve, reject) => {
});
}
async function drawCanvas(){
var canvas = document.querySelector('canvas');
var context = Context('2d');
var ratio = getPixelRatio(context); // 关键代码
canvas.width = 300 * ratio; // 画布宽度
canvas.height = 300 * ratio; // 画布⾼度
var divWidth = 300 * ratio; // ⽤于内容居中
var divHeight = 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 = Blob((Blob)=>{
//上传七⽜云如何启用javascript功能
});
}
最终⽣成的图⽚终于清晰了...只需要根据dom的offsetWidth等适配不同屏幕就可以了。
总结
如果对图⽚的清晰度要求不⾼,或者图⽚需求是⽣成缩略图的情况下。采⽤ html2canvas 是⾮常不错的选择。
否则,还是⽤canvas绘制出的图⽚更清晰。
到此这篇关于JS如何实现页⾯截屏功能的⽂章就介绍到这了,更多相关JS页⾯截屏功能内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论