[h5]自定義海報生成

功能需求:獲取海報參數(shù)自定義生成一張帶二維碼海報。

效果如下:
image

元素:主要分成背景圖,用戶信息和帶用戶信息的二維碼(由前端生成);

步驟:先根據(jù)設(shè)計完成布局設(shè)計->將這張海報的html元素生成為canvas->將該canvas轉(zhuǎn)化成圖片;

  • 步驟1:請求數(shù)據(jù),成功后主要是二維碼的生成(使用qrcodejs2)
// 生成二維碼
    qrcodeCreate() {
      const _this = this;
      if (_this.poster_params.code_url) {
        let qrcodeDom = document.getElementById("qrcode");
        qrcode = new QRCode("qrcode", {
          width: parseInt(qrcodeDom.clientWidth), // 設(shè)置寬度,單位像素
          height: parseInt(qrcodeDom.clientHeight), // 設(shè)置高度,單位像素
          text: _this.poster_params.code_url // 設(shè)置二維碼內(nèi)容或跳轉(zhuǎn)地址
        });
      } else {
        _this.isLoading = false;
        _this.isFailed = true;
        return _this.$toast.center("海報跑走了~");
      }
    }
  • 步驟2:設(shè)計海報canvas

注意是內(nèi)部圖片必須有效加載才能生成成功,所以需要先判斷圖片鏈接的有效性,之后等圖片完全加載完成之后再轉(zhuǎn)為canvas;還有在圖片為不同域的情況也可能會產(chǎn)生生成失敗的現(xiàn)象,所以需要先將跨域圖片轉(zhuǎn)換為base64格式。

// 創(chuàng)建海報canvas
let box = document.getElementById("poster-box"); // 海報盒子
      let c_width = box.offsetWidth;
      let c_height = box.offsetHeight;
      let canvas = document.createElement("canvas");
      let context = canvas.getContext("2d");
      // 獲取根據(jù)屏幕分辨率,來設(shè)置canvas的寬高以獲得高清圖片
      let devicePixelRatio = window.devicePixelRatio || 2;
      let backingStoreRatio =
        context.webkitBackingStorePixelRatio ||
        context.mozBackingStorePixelRatio ||
        context.msBackingStorePixelRatio ||
        context.oBackingStorePixelRatio ||
        context.backingStorePixelRatio ||
        1;
      let ratio = devicePixelRatio / backingStoreRatio;
      canvas.width = c_width * ratio;
      canvas.height = c_height * ratio;
      canvas.style.width = c_width + "px";
      canvas.style.height = c_height + "px";
      canvas.style.position = "absolute";
      canvas.style.left = "50%";
      canvas.style.top = "50%";
      canvas.style.transform = "translate(-50%, -50%)";
      canvas.style.zIndex = "10";
      canvas.style.opacity = "0";
      // canvas的頁面位置自行調(diào)整
      let scrollTop =
        document.documentElement.scrollTop ||
        window.pageYOffset ||
        document.body.scrollTop;
      let scrollLeft =
        document.documentElement.scrollLeft ||
        window.pageXOffset ||
        document.body.scrollLeft;
      let transTop =
        screenTop -
        (document.getElementsByClassName("poster-view-content")[0].offsetTop -
          c_height / 2);
      let transLeft = (c_width - window.innerWidth) / 2;
      context.scale(ratio, ratio);
      // canvas的位置要保證與div位置相同。
      context.translate(transLeft, transTop);
// 背景圖片
      let img = new Image();
      let canvas2 = document.createElement("canvas");
      let ctx = canvas2.getContext("2d");
      img.crossOrigin = "Anonymous";
      img.src = _this.poster_params.share;
      img.onload = function() {
        if (img.width > 0) {
          canvas2.height = img.height;
          canvas2.width = img.width;
          ctx.drawImage(img, 0, 0);
          let dataURL = canvas2.toDataURL("image/png");
          document.getElementById("poster-bg").setAttribute("src", dataURL);
          canvas2 = null;
          _this.getCard(box, canvas, c_width, c_height); // 生成海報canvas
        } else {
          _this.isLoading = false;
          _this.isFailed = true;
          return _this.$toast.center("海報跑走了~");
        }
      };
      img.onerror = function() {
        _this.isLoading = false;
        _this.isFailed = true;
        return _this.$toast.center("海報跑走了~");
      };
  • 步驟3:在所有圖片都加載以及轉(zhuǎn)換成功后,可以生成海報canvas并轉(zhuǎn)換生成圖片(使用html2canvas)
        // 每次圖片加載成功后都會請求執(zhí)行該函數(shù)(但是要在所有圖片都加載成功后才能真正生成canvas)
    getCard(box, canvas, c_width, c_height) {
      const _this = this;
      _this.cnt++; // 對已加載成功的圖片數(shù)進行判斷
      if (_this.cnt < 3) return; // 所有圖片都成功可以生成
      html2canvas(box, {
        allowTaint: true,
        useCORS: true,
        canvas: canvas,
        width: c_width,
        height: c_height
      }).then(function(canvas) {
        canvas.setAttribute("id", "my-canvas"); //添加屬性
        box.appendChild(canvas);
        // 轉(zhuǎn)換圖片得到base64格式
        let dataURL = canvas.toDataURL("image/png");
        let img = new Image();
        img.src = dataURL;
        img.className = "cardImg";
        img.style.position = "absolute";
        img.style.left = "50%";
        img.style.top = "50%";
        img.style.transform = "translate(-50%, -50%)";
        img.style.zIndex = "150";
        img.style.width = c_width + "px";
        img.style.height = c_height + "px";
        box.appendChild(img);
        // 生成成功
        _this.$emit('createPosterSuccess', dataURL);
        _this.isLoading = false;
        _this.isSuccess = true;
      });
    }

大致就完成了,主要在于異步的問題,在圖片base64格式轉(zhuǎn)換的時候也要判斷二維碼是否生成成功。
還有生成到成為一張圖片還是需要一定時間,所以最好有一個生成中的加載狀態(tài)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容