h5微信生成海报并保存为图片(含二维码)

2,291 阅读1分钟

h5生成海报并保存为图片(含二维码)

笔者有个需求是在h5移动端微信浏览器里做一个画报,可以长按保存图片到手机。遇到了大坑。写了一个demo来记录一下如何实现此功能的。先展示最终效果。

image.png

技术栈

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)
  • 目前可实现绘制二维码并将此二维码转为图片的功能了,长按图片即可保存。

五、在二维码里面中间的位置加上一个图片,二维码外面增加白边

image.png

  • 实现思路:在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>