vue-cli(微信公衆號)中網頁轉成canvas並保存爲圖進行長按分享

先上效果圖:

圖1 點擊按鈕生成圖2 (個人分享海報分享,點擊分享彈框顯示)

圖3 點擊按鈕生成圖4 (商品詳情分享,點擊分享替換掉頁面內容)

所需依賴包:qrcodejs2 html2canvas  (具體引入方式請自行點擊查看,不做描述)  html2canvas 文檔

 

下面直接上代碼(針對圖1 2):

HTML: 簡單佈局:左上角用戶信息,右下角通過qrcode生成分享二維碼。大的背景圖使用的img定位實現。(最開始使用的是背景圖,但是生成的海報圖比較模糊,且按照網上的方法並沒有解決掉,於是更換了img標籤)

<template>
  <div>
    <div class="root" id="codeImg" :style="'width:'+ htmlW +'px;height:'+htmlW*1.777 +'px;'">
      <!-- background-image: url('+BackgroundMap+'); -->
      <img class="backMap" :src="BackgroundMap" alt>
      <!-- 推廣碼 -->
      <div class="user-info">
        <img :src="userImg" alt>
        <p>
          <span>{{userInfo.NickName}}</span>
          <br>
          <span>我爲xxxx代言</span>
        </p>
      </div>
      <div class="qrcode">
        <div id="qrcode" style="text-align:center"></div>
        <div>長按此二維碼
          <br>註冊成爲xxxx會員
        </div>
      </div>
      <div id="canvas"></div>
      <canvas id="aaa"></canvas>
      <mt-popup v-model="popupShare" class="popup-share share-code">
        <div class="share">
          <div class="share-img"></div>
          <!-- <div class="footer" @click="downImg()">長按進行分享操作 </div> -->
        </div>
      </mt-popup>
    </div>
    <!-- 分享 -->
    <div class="share-icon" @click="openShare()">
      <img src="../../../../../static/images/share.png" alt>
    </div>
  </div>
</template>

Javascript: 核心代碼:

import QRCode from 'qrcodejs2'
import html2canvas from 'html2canvas'

// 生成二維碼
qrcode (qn) {
      /* eslint-disable no-new */
      new QRCode('qrcode', {
        width: 85,
        height: 85,
        text: qn
      })
    },
this.qrcode('xxxxxx')


// 點擊生成海報
this.downImg ()
downImg () {
      var _this = this
      var canvas2 = document.createElement('canvas')
      let _canvas = document.querySelector('.root')
      var w = parseInt(window.getComputedStyle(_canvas).width)
      var h = parseInt(window.getComputedStyle(_canvas).height)
      // 將canvas畫布放大若干倍,然後盛放在較小的容器內,就顯得不模糊了
      canvas2.width = w * 2
      canvas2.height = h * 2
      canvas2.style.width = w + 'px'
      canvas2.style.height = h + 'px'
      // 可以按照自己的需求,對context的參數修改,translate指的是偏移量
      //  var context = canvas.getContext("2d");
      //  context.translate(0,0);
      var context = canvas2.getContext('2d')
      context.scale(2, 2)
      let opts = {
        scale: 2,
        allowTaint: true,
        canvas: canvas2,
        logging: true,
        imageTimeout: 0,
        // width: w, // dom 原始寬度
        // height: h,
        dpi: window.devicePixelRatio * 960
      }
      html2canvas(document.querySelector('.root'), opts).then(function (canvas) {
        document.querySelector('.share-img').innerHTML =
          '<div class="qrimg"><p style="font-size:0.32rem;color:#808080;line-height:1.173rem">長按上圖進行分享操作</p></div>'
        // 在p標籤前面插入圖片insertBefore(new,item[0]) 在父元素最後插入appendChild(new)
        document
          .querySelector('.qrimg')
          .insertBefore(
            _this.convertCanvasToImage(canvas),
            document.querySelector('.share-img p')
          )
        document.querySelector('.share-img img').style.width = '100%'
      })
    },
// 從 canvas 提取圖片 image
    convertCanvasToImage (canvas) {
      var image = new Image()
      image.src = canvas.toDataURL('image/png')
      return image
    },
// 將圖片轉base64  後臺接口
    ExchangeImage (index, url) {
      this.$http
        .get('/api/APP_Home/ExchangeImage', { image: url })
        .then(res => {
          if (index === 1) {
            this.userImg = res.Result
          } else if (index === 2) {
            this.BackgroundMap = res.Result
          }
        })
    },

Style: (使用了scss)

.root {
  width: 100%;
  // background-image: url("/static/images/code_bg.jpg");
  background-size: 100% 100%;
  background-repeat: no-repeat;
  position: relative;
  .backMap {
    position: absolute;
    top: 0;
    width: 100%;
  }
  .user-info {
    padding: 0.5rem;
    position: absolute;
    top: 0;
    width: 100%;
    img {
      width: 1.333rem;
      height: 1.333rem;
      float: left;
      margin-right: 0.265rem;
    }

    p {
      color: #262626;
      font-size: 0.32rem;
      line-height: 0.6665rem;
      font-family: "楷體";
      font-weight: 600;
    }
  }

  .qrcode {
    position: absolute;
    bottom: 0.4rem;
    right: 0.265rem;
    margin-top: 0.5rem;

    div {
      text-align: center;
      color: #fff;
      font-family: "楷體";
      font-size: 0.32rem;
    }
  }

  .popup-share {
    width: 80%;
    // height: 14rem;
    padding: 0.265rem 0.265rem 0;

    .share {
      height: 100%;
      width: 100%;
      text-align: center;
      position: relative;
      img {
        width: 100%;
      }
    }
  }
}

 

bug:

       1、最開始做的時候所有的圖片都是從static文件夾下直接引入的,點擊分享生成的海報圖僅僅是模糊的問題。但是和後臺對接接口的時候圖片需要更換爲網路地址。導致生成海報的時候只要是網絡圖片都直接報跨域錯誤。經過一番倒騰發現需要設置useCORS參數爲true,但是我添加修改之後並沒有效果。查看過dom標籤之後發現,所有跨域的圖片都是因爲使用的網絡地址,而本地引入的圖片渲染時路徑修改爲base64圖片路徑。最終讓後臺新增了一個網絡圖片轉base64的接口 ExchangeImage() 講所有的網絡地址在渲染頁面的時候使用base64。這樣就解決了問題

       2、該bug是圖3 4出現的。(該問題歡迎討論)最初的商品分享效果是在商品詳情頁點擊分享按鈕直接通過popup彈框顯示所需要分享的信息,然後點擊分享生成海報圖。開發中沒有什麼問題,後來上線測試的時候發現在微信開發工具中以及大部分安卓手機中點擊分享的時候最終生成的海報圖的內容統一會向右側移動一個不固定的位置。經過測試發現是通過html2canvas將網頁生成canvas的時候canvas的內容右移了。使用translate(x,y)進行偏移修改沒有效果。(目前沒有解決掉,歡迎路過的賜教!)考慮到可能是html2canvasJS版本的問題,於是單獨引入了0.5版本的代碼。結果使用translate()後安卓手機果然可以進行解決左右偏移的問題,但是出現了上下偏移,並且ios手機上也出現了不確定的偏移問題。/手動無奈/。

       經過一盤折騰想到可能是因爲popup彈框的衝突問題吧(其實圖1也是點擊後彈出popup,然後渲染海報圖),最終按照圖1的思路將頁面修改,點擊商品詳情頁的分享跳轉圖3 點擊圖3的按鈕生成圖4講圖3的內容替換爲分享海報


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章