h5生成海报并保存为图片(含二维码)
笔者有个需求是在h5移动端微信浏览器里做一个画报,可以长按保存图片到手机。遇到了大坑。写了一个demo来记录一下如何实现此功能的。先展示最终效果。
技术栈
1.qrcode.js
qrcode.js是专门用js于生成二维码的插件。
2.html2canvas.js
注意:一定不要引入最新的js,去找v1.0.0-rc.4,好吗!!!因为我一开始下载的最新版本的,在安卓手机的微信浏览器很完美,但是ios13版本html2canvas失效了,其他浏览器可以生效。网上搜了很多办法,让回退到v1.0.0-rc.4版本,所以放上这个版本的链接:
3.此文示例也使用了jquery
一、准备好html和css
<style>
* {
box-sizing: border-box;
}
body {
width: 100vw;
height: 100vh;
background: #f5da55;
}
.capture {
/* padding: 30px; */
text-align: center;
background: #f5da55;
color: #000;
width: 100vw;
height: 100vh;
position: absolute;
box-sizing: border-box;
}
.my_img {
width: 100vw;
height: 100vh;
position: absolute;
background: #f5da55;
/* display: none; */
}
</style>
<!-- 用于画canvas的容器 -->
<div id="capture" class="capture">
<h5>窗边的可爱小豆豆</h5>
<!-- 用于画二维码的容器 -->
<div id="qrcode"></div>
<div>长按保存图片</div>
</div>
<!-- 用于展示长按保存的图片容器 -->
<img src="" alt="" id="imgShow" class="my_img" />
二、生成二维码(具体参数配置可参考文档)
// 生成二维码
var qrcode = new QRCode(document.getElementById("qrcode"), {
text: window.location.href, //url路径
width: 100, // 二维码宽度
height: 100, // 二维码高度
})
三、html绘制成canvas
// html绘制canvas
html2canvas(document.querySelector("#capture"), { useCORS: true })
.then((canvas) => {
document.body.appendChild(canvas)
})
.catch((err) => {
console.log("err", err)
})
四、canvas转成img并显示到页面中
// canvas转为图片
const _imgSrc = canvas.toDataURL("image/png", 1)
// 将其他容器隐藏
$("#capture").hide()
$("canvas").hide()
$("#imgShow").attr("src", _imgSrc)
- 目前可实现绘制二维码并将此二维码转为图片的功能了,长按图片即可保存。
五、在二维码里面中间的位置加上一个图片,二维码外面增加白边
-
实现思路:在qrcode元素外面包一个div来加外面白边的样式,在qrcode里面加上img,路径为想加的图片,为了实现样式,本文例子又在里面嵌套了一层p。
-
元素层级如下:
<div class="code_box" id="code_box">
<div id="qrcode" class="qrcode">
<p class="myp">
<img src="static/images/common/tx_5.png" alt="" class="myImg" />
</p>
</div>
</div>
- 样式如下:
.code_box{
text-align: center;
margin: auto;
background: #fff;
border-radius: 5px;
/* border:1px solid #ddd; */
padding:10px;
width: 140px;
}
.qrcode{
position:relative ;
position: relative;
text-align: center;
display: flex;
justify-content: center;
align-content: center;
}
.myp{
width: 20px;
height: 20px;
position: absolute;
background-color: #fff;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
margin: 0;
}
.myImg{
width:20px;
}
五、完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>海报示例</title>
<style>
.code_box{
text-align: center;
margin: auto;
background: #fff;
border-radius: 5px;
/* border:1px solid #ddd; */
padding:10px;
width: 140px;
}
.qrcode{
position:relative ;
position: relative;
text-align: center;
display: flex;
justify-content: center;
align-content: center;
}
.myp{
width: 20px;
height: 20px;
position: absolute;
background-color: #fff;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
margin: 0;
}
.myImg{
width:20px;
}
</style>
</head>
<body>
<section class="main_content" style="text-align: center">
<h3>筹款二维码</h3>
<div class="code_box" id="code_box">
<div id="qrcode" class="qrcode">
<p class="myp">
<img src="static/images/common/tx_5.png" alt="" class="myImg" />
</p>
</div>
</div>
<img src="" alt="" class="share_img middle" id="imgShow" style="height: 130px" />
<h6>长按二维码保存到相册</h6>
</section>
<script type="text/javascript" src="static/js/common/jquery-3.4.1.min.js"></script>
<script type="text/javascript" src="static/js/common/common.js"></script>
<script type="text/javascript" src="static/components/qrcode/qrcode.js"></script>
<script type="text/javascript" src="static/components/html2canvas/html2canvas.min.js"></script>
<script type="text/javascript">
let path =
window.location.protocol +
"//" +
window.location.host +
"/index.html?id=" +
id
console.log("path", path)
var qrcode = new QRCode(document.getElementById("qrcode"), {
text: path,
width: 130,
height: 130,
})
html2canvas(document.querySelector("#code_box")).then((canvas) => {
document.body.appendChild(canvas)
var imgUrl = canvas.toDataURL("image/png")
// console.log("base64编码数据:", imgUrl)
$("#imgShow").attr("src", imgUrl)
$("#imgShow").show()
$("#code_box,canvas").remove()
})
</script>
</body>
</html>