上次分享的通过php方式生成的海报图片总有写字是模糊的,多次调试没有解决问题,后来干脆想办法在前端页面直接搞,请教了前端的大佬后分享了一个
很不错的js脚本,可以快速实现html转换成canvas画布,然后自行通过其他逻辑下载截图即可。
效果图:

html2canvas.js引入到项目进行操作即可,可以对指定的元素进行“截图”模式。
特别注意:图片千万不要用background方式设置,否则会模糊,之前用span的background设置图片,发现很模糊,经过查阅资料发现用img标签替代就行了,这样才很清晰。
案例代码(自己非专业前端,不喜勿喷,基于weui排版写的页面):
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>海报分享</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/weui/css/weui.css">
<link rel="stylesheet" href="/static/weui/css/weuix.css">
<style>
.info-text{
width: 70%;
float: left;
}
.info-img{
width: 30%;
float: right;
line-height: 100%;
}
.info-img img{
max-height: 100%;
max-width: 100%;
}
.info-img .qrcode{
width: 100%;
}
#content{
margin:0 auto;
max-width: 650px;
}
.tip{
font-size: 18px;
text-align: center;
padding: 10px;
font-weight: bold;
}
</style>
</head>
<body ontouchstart>
<div>
<div id="content">
<ul>
<li style="width: 100%">
<img src="/upload/test/share/1.jpg" style="max-width: 100%;"/>
</li>
<li style="width: 100%;background: white;overflow: hidden;padding: 10px">
<div>
<b style="overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;">正宗初生蛋小个头40枚10枚散养农村散养初生鸡蛋现捡新鲜鸡蛋批发</b> <br>
¥ <b style="color: red">27.9</b>
<div style="color: grey;font-size: 14px">识别右侧的二维码进入了解详情</div>
</div>
<div>
<img src="/upload/test/share/qc.png" alt="">
</div>
<div style="clear: both"></div>
</li>
<li>
<img src="/upload/test/share/1.jpg" style="max-width:100%"/>
</li>
<li>
<img src="/upload/test/share/6.jpg" style="max-width:100%"/>
</li>
<li>
<img src="/upload/test/share/2.jpg" style="max-width:100%"/>
</li>
<li>
<img src="/upload/test/share/3.jpg" style="max-width:100%"/>
</li>
<li>
<img src="/upload/test/share/4.jpg" style="max-width:100%"/>
</li>
<li>
<img src="/upload/test/share/5.jpg" style="max-width:100%"/>
</li>
</ul>
</div>
<div></div>
<div>
<p class="f-red tip">请长按图片保存到本地并分享</p>
</div>
</div>
<br>
<br>
<script src="/static/weui/js/zepto.min.js"></script>
<script src="/static/weui/js/zepto.weui.js"></script>
<script type="text/javascript" src="/static/js/html2canvas.min.js"></script>
<script type="text/javascript">
//用JavaScript将画布保持成图片格式
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image;
}
$.showLoading();
var c = document.getElementById("content")
var options = {
dpi: 300,
scale: 2, // 添加的scale 参数
// width:500,
useCORS: true // 【重要】开启跨域配置
};
html2canvas(c,options).then(function(canvas) {
//$(".res").html(canvas)
$(c).html("<img src='"+canvas.toDataURL('image/png')+"' style='max-width: 100%'/>")
/*var a = document.createElement('a')
//a.href = canvas.toDataURL('image/png') // 将画布内的信息导出为png图片数据
// a.download = '分享图片' // 设定下载名称
//a.className='weui-btn weui-btn-area weui-btn_primary'
// a.innerHTML='保存海报'
$(".btn").html(a)*/
});
$.hideLoading();
</script>
</body>
</html>html2canvas的参数 http://html2canvas.hertzen.com/configuration:


调整js代码,设置scale比例,并自动下载为png:
var c = document.getElementById("content")
var options = {
scale:1.3,//按比例缩放
dip:2000,//没有发现有用
}
html2canvas(c,options).then(function(canvas) {
$(c).html(canvas)
var a = document.createElement('a')
a.href = canvas.toDataURL('image/png') // 将画布内的信息导出为png图片数据
a.download = '分享图片' // 设定下载名称
a.click() // 点击触发下载
});另外,分享两个画布和图片互转的函数(或许有用哦):
//用JavaScript将画布保持成图片格式
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image;
}
//使用JavaScript将图片拷贝进画布
function convertImageToCanvas(image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext("2d").drawImage(image, 0, 0);
return canvas;
}遇到的坑和解决方案:
问题1:图片跨域问题,比如拉取第三方平台的图片无法加载
解决:搭建本地图片资源转发服务,这里我用timthumb.php做,可以看这篇文章 如何在PHP中动态调整图像大小?今天分享这个小小的timthumb.php满足你的需求
问题2:图片截图显示不完整问题,滚动到下面开始截图时顶部空白
解决:页面加载完成后开始截图设置回到最顶部:document.body.scrollTop = document.documentElement.scrollTop = 0;
问题3:在移动端无法显示图片的问题,导致小图都不显示
解决:还是跨域问题,移动端和web端不一样,给图片添加匿名跨域属性:crossorigin="anonymous" 并设置useCORS: true // 【重要】开启跨域配置(不需要设置allowTaint: true,//允许跨域图片),然后就解决了。
问题4:进入页面直接生成的方式还是没有完整截图,经常只有部分
解决:进入页面后等页面加载完成设置一个延迟渲染,比如1秒:
setTimeout(function (){
start();
},1000)问题5:图片过大也会导致生成画布不完整
解决:还是通过图片代理,重新设置图片的大小
优化后完整版:
<!doctype html>
<html lang="zh">
<head>
<meta charset="utf-8">
<title>海报分享</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/weui/css/weui.css">
<link rel="stylesheet" href="/static/weui/css/weuix.css">
<style>
.info-text {
width: 70%;
float: left;
}
.info-img {
width: 30%;
float: right;
line-height: 100%;
}
.info-img img {
max-height: 100%;
max-width: 100%;
}
.info-img .qrcode {
width: 100%;
}
#content {
margin: 0 auto;
max-width: 800px;
/*border: 2px chartreuse dashed;*/
}
.tip {
font-size: 18px;
text-align: center;
padding: 10px;
font-weight: bold;
}
img.s-img {
height: 121px;
}
.weui-panel {
background-color: #FFFFFF;
margin-top: 10px;
position: unset;
overflow: hidden;
/* bottom: 0; */
text-align: center;
}
</style>
</head>
<body ontouchstart>
<div class="page-bd-15">
<div class="weui-feeds" id="content">
<ul>
<li style="width: 100%;text-align: center">
<img src="https://source.alipay168.cn/wxauth.alipay168.cn/mstore/1f0e3dad99908345f7439f8ffabdffc4.png?v=1584009797" style="max-width:100%" />
</li>
<li style="width: 100%;background: white;overflow: hidden;padding: 10px;max-width: 100%">
<div class="info-text">
<b style="overflow: hidden;text-overflow: ellipsis; display: -webkit-box;-webkit-line-clamp: 2;-webkit-box-orient: vertical;">爆款格蒙网红7天迷你口红套装多色一盒持久不脱色国货彩妆</b> <br>
¥ <b style="color: red">28.99</b>
<div style="color: grey;font-size: 14px">识别右侧的二维码进入了解详情</div>
</div>
<div class="info-img">
<img class="qrcode" src="http://wei.test.top/upload/mstore/poster/qrcode/19_1f0e3dad99908345f7439f8ffabdffc4.png" alt="">
</div>
<div style="clear: both"></div>
</li>
<li style="text-align: center">
<img alt="" crossorigin="anonymous" class="s-img" src="http://wei.test.top/index/tools/timg.html?src=http://wxauth.alipay168.cn/ueditor/php/upload/image/20200312/1584009531198704.jpg&w=121&q=100" style="max-width:100%"/>
</li>
<li style="text-align: center">
<img alt="" crossorigin="anonymous" class="s-img" src="http://wei.test.top/index/tools/timg.html?src=http://wxauth.alipay168.cn/ueditor/php/upload/image/20200312/1584009532970739.jpg&w=121&q=100" style="max-width:100%"/>
</li>
<li style="text-align: center">
<img alt="" crossorigin="anonymous" class="s-img" src="http://wei.test.top/index/tools/timg.html?src=http://wxauth.alipay168.cn/ueditor/php/upload/image/20200312/1584009532388616.jpg&w=121&q=100" style="max-width:100%"/>
</li>
<li style="text-align: center">
<img alt="" crossorigin="anonymous" class="s-img" src="http://wei.test.top/index/tools/timg.html?src=http://wxauth.alipay168.cn/ueditor/php/upload/image/20200312/1584009532120428.jpg&w=121&q=100" style="max-width:100%"/>
</li>
<li style="text-align: center">
<img alt="" crossorigin="anonymous" class="s-img" src="http://wei.test.top/index/tools/timg.html?src=http://wxauth.alipay168.cn/ueditor/php/upload/image/20200312/1584009533453186.jpg&w=121&q=100" style="max-width:100%"/>
</li>
<li style="text-align: center">
<img alt="" crossorigin="anonymous" class="s-img" src="http://wei.test.top/index/tools/timg.html?src=http://wxauth.alipay168.cn/ueditor/php/upload/image/20200312/1584009533432512.jpg&w=121&q=100" style="max-width:100%"/>
</li>
</ul>
</div>
<div class="res"></div>
<div class="weui-panel" >
<p class="f-red tip">请长按图片保存到本地并分享</p>
</div>
</div>
<br>
<br>
<script src="/static/weui/js/zepto.min.js"></script>
<script src="/static/weui/js/zepto.weui.js"></script>
<script type="text/javascript" src="/static/js/html2canvas.min.js"></script>
<script type="text/javascript">
function start(){
//先跳到最顶端(如果有操作按钮在底部的特别重要)
document.body.scrollTop = document.documentElement.scrollTop = 0;
var c = document.getElementById("content")
var options = {
dpi: 300,
scale: 2, // 添加的scale 参数
//width:500,
//height:1000,
async:true,//是否异步
onclone:function(){
$.showLoading('海报生成中...');
},
proxy:null,//Url到 代理 ,用于加载跨源图像。如果留空,则不会加载跨原始图像。
imageTimeout:10000,//加载图像的超时(以毫秒为单位,设置 0 为禁用超时
// allowTaint: true,//允许跨域图片
taintTest: false,//是否在渲染前测试图片
useCORS: true // 【重要】开启跨域配置
};
html2canvas(c,options).then(function(canvas) {
$.hideLoading();
$(c).html("<img src='"+canvas.toDataURL('image/png')+"' style='max-width: 100%'/>");
/*var a = document.createElement('a')
a.href = canvas.toDataURL('image/png') // 将画布内的信息导出为png图片数据
a.download = '分享图片' // 设定下载名称
a.className='weui-btn weui-btn-area weui-btn_primary'
a.innerHTML='保存海报'
$(".btn").html(a)*/
});
}
//用JavaScript将画布保持成图片格式
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image;
}
$(function (){
setTimeout(function (){
start();
},1000)
})
</script>
</body>
</html>效果:
