[h5]自定义海报生成

功能需求:获取海报参数自定义生成一张带二维码海报。

效果如下:
image

元素:主要分成背景图,用户信息和带用户信息的二维码(由前端生成);

步骤:先根据设计完成布局设计->将这张海报的html元素生成为canvas->将该canvas转化成图片;

  • 步骤1:请求数据,成功后主要是二维码的生成(使用qrcodejs2)
// 生成二维码
    qrcodeCreate() {
      const _this = this;
      if (_this.poster_params.code_url) {
        let qrcodeDom = document.getElementById("qrcode");
        qrcode = new QRCode("qrcode", {
          width: parseInt(qrcodeDom.clientWidth), // 设置宽度,单位像素
          height: parseInt(qrcodeDom.clientHeight), // 设置高度,单位像素
          text: _this.poster_params.code_url // 设置二维码内容或跳转地址
        });
      } else {
        _this.isLoading = false;
        _this.isFailed = true;
        return _this.$toast.center("海报跑走了~");
      }
    }
  • 步骤2:设计海报canvas

注意是内部图片必须有效加载才能生成成功,所以需要先判断图片链接的有效性,之后等图片完全加载完成之后再转为canvas;还有在图片为不同域的情况也可能会产生生成失败的现象,所以需要先将跨域图片转换为base64格式。

// 创建海报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");
      // 获取根据屏幕分辨率,来设置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的页面位置自行调整
      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:在所有图片都加载以及转换成功后,可以生成海报canvas并转换生成图片(使用html2canvas)
        // 每次图片加载成功后都会请求执行该函数(但是要在所有图片都加载成功后才能真正生成canvas)
    getCard(box, canvas, c_width, c_height) {
      const _this = this;
      _this.cnt++; // 对已加载成功的图片数进行判断
      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);
        // 转换图片得到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格式转换的时候也要判断二维码是否生成成功。
还有生成到成为一张图片还是需要一定时间,所以最好有一个生成中的加载状态。

你可能感兴趣的:([h5]自定义海报生成)