美文网首页
小程序生成海报遇见的坑

小程序生成海报遇见的坑

作者: wyc0859 | 来源:发表于2019-04-21 11:49 被阅读0次

    生成海报,涉及小程序二维码生成,多图片合成,图片定位居中,多行文字,文字居中,禁止滚动等问题

    1、首先base64图片不能和canvas合成
    2、url图片必须用wx.downloadFile()先下载,返回结果为http://tmp/wx0b6251f....是正确结果
    3、小程序二维码是在API服务器端生成的,点击

    33.png
    //解决禁止滚动问题
    <!-- catchtouchmove="preventTouchMove" -->
    <!--  disable-scroll="true" bindtouchstart="touchStart" -->
     <!--  disable-scroll="true" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd" -->
    
    <view class='haibao' wx-if="{{haib}}" catchtouchmove="preventTouchMove">
      <view class='hb'>
        <view class='hb_01' bindtap='close_hb' hidden="{{btn_save}}">
          <image src='/imgs/xc.png'></image>
        </view>
        <view class='hb_02 poste_box' id='canvas-container'>
          <canvas canvas-id="myCanvas" style="width:100%;height:420px;" disable-scroll="true" bindtouchstart="touchStart"  />
          <!-- bindtouchmove="touchMove" bindtouchend="touchEnd" -->
        </view>
        <view class='hb_03' hidden="{{btn_save}}">
          <van-button round type="danger" bindtap="save"> 保存到本地</van-button>
        </view>
      </view>
      <v-black></v-black>
    </view>
    
    import {  HB } from '../../util/hb.js';
    //显示海报框,并开始生成海报
      show_hb() {
        const that = this
        this.setData({
          haib: true,
          share_t: false,
          btn_save: false,
        })
        const obj = {
          id: 2,
          imgs: https://www.phps.shop/1.jpg,
          name: 'aaa',
          price: 1,
          market_price: 2,
        }
        HaoBao.create_hb(obj);
      },
    
    //保存海报
      save() {
        const that=this
        HaoBao.save(res=>{ 
          if(res==1){
            that.setData({
              haib: false,
              share_t: false,
              btn_save: true,
            })
          }else{
            wx.showToast({
              title: '保存失败'
            })
          } 
        }) 
      } 
    

    封装好的海报类

    import {
      HTTP
    } from 'http.js';
    const http = new HTTP
    class HB {
      cardInfo = {
        Company: '-- 如花商城 --',
        bgimg: 'https://wy.phps.shop/hb_bg.png',  //背景图
        wximg: 'https://wy.phps.shop/wx.png', //固定二维码
        goodsimg: '',
        Name: '', 
        Price: '',
        market_price: '',
        id:''
      } 
      create_hb(obj){ 
        obj.imgs = obj.imgs.replace('http://', 'https://');
        this.cardInfo.Name=obj.name
        this.cardInfo.Price = '¥ '+obj.price
        this.cardInfo.market_price = '原价 '+obj.market_price
        this.cardInfo.goodsimg = obj.imgs
        this.cardInfo.goods_id = obj.id  
        this.get_codeimg()
      }
    
      //获取小程序码
      get_codeimg() { 
        const that = this
        const id = that.cardInfo.id
        //that.getQrCode(that.cardInfo.wximg) //使用固定二维码
        /*  动态获取二维码  */
        http.request({
          url: '/get_codeimg',
          data: {
            path: 'pages/goods/index?id=' + id
          }
        }).then(res => {
          that.getQrCode(res)
        })
      }
    
      //下载二维码图片,虽然已经有二维码图片了,但必须wx.downloadFile后才能绘制
      getQrCode(urls) {
        var that = this;
        console.log('二维码0', urls)
        wx.showLoading({
          title: '生成中...',
          mask: true,
        })
        wx.downloadFile({
          url: urls, //二维码路径
          success: function (res) {
            wx.hideLoading();
            if (res.statusCode === 200) {
              var codeSrc = res.tempFilePath;
              console.log('二维码1', res)
              that.down_bg(codeSrc);
            } else {
              wx.showToast({
                title: '二维码下载失败!',
                icon: 'none',
                duration: 2000,
                success: function () {
                  var codeSrc = "";
                  that.down_bg(codeSrc);
                }
              })
            }
          }
        })
      }
    
      //下载背景图
      down_bg(urls) {
        var that = this;
        wx.showLoading({
          title: '生成中...',
          mask: true,
        })
        console.log('bgimg:', that.cardInfo.bgimg)
        wx.downloadFile({
          url: that.cardInfo.bgimg,
          success: function(res) {
            console.log('bgcode:', res.tempFilePath)
            wx.hideLoading();
            if (res.statusCode === 200) {
              var bg = res.tempFilePath;
              that.getAvaterInfo(bg, urls);
            } else {
              wx.showToast({
                title: '商品图片下载失败!',
                icon: 'none',
                duration: 2000,
                success: function() {
                  var bg = "";
                  that.getAvaterInfo(bg, urls);
                }
              })
            }
          }
        })
      }
    
      //下载商品图片
      getAvaterInfo(bg, urls) {
        var that = this; 
        wx.showLoading({
          title: '生成中...',
          mask: true,
        }) 
        wx.downloadFile({
          url: that.cardInfo.goodsimg, //图片路径
          success: function(res) {
            console.log('goodsimg:', res.tempFilePath)
            wx.hideLoading();
            if (res.statusCode === 200) {
              var avaterSrc = res.tempFilePath; //下载成功返回结果
              that.sharePosteCanvas(bg, urls, avaterSrc); //生成海报
            } else {
              wx.showToast({
                title: '商品图片下载失败!',
                icon: 'none',
                duration: 2000,
                success: function() {
                  var avaterSrc = "";
                  that.sharePosteCanvas(bg, urls, avaterSrc); 
                }
              })
            }
          }
        })
      }
      
      //绘制海报
      sharePosteCanvas(bj, codeSrc, avaterSrc) {
        wx.showLoading({
          title: '生成中...',
          mask: true,
        })
        let {
          windowWidth
        } = wx.getSystemInfoSync();
        windowWidth = windowWidth * 0.72 //css中设置的是72%宽
        console.log('w:', windowWidth)
        var that = this;
        var cardInfo = that.cardInfo; //需要绘制的数据集合
        const ctx = wx.createCanvasContext('myCanvas'); //创建画布
        var width = "";
        wx.createSelectorQuery().select('#canvas-container').boundingClientRect(function(rect) {
          var height = rect.height;
          var right = rect.right;
          width = rect.width * 0.8;
          var left = 15;
          ctx.setFillStyle('#fff');
          ctx.fillRect(0, 0, rect.width, height);
    
          //背景图片
          if (bj) {
            ctx.drawImage(bj, 0, 0, windowWidth, 420);
            ctx.setFontSize(14);
            ctx.setFillStyle('#fff');
            ctx.setTextAlign('left');
          }
          //公司名称 
          if (cardInfo.Company) {
            ctx.setFontSize(14);
            ctx.setFillStyle('#333');
            ctx.setTextAlign('center');
            let fw = ctx.measureText(cardInfo.Company) //计算文字总宽度,ctx.setTextAlign('leftr')时有用
            ctx.fillText(cardInfo.Company, windowWidth / 2, 25);  /*参数为:图片,左,上*/
          }
    
          // //商品图片
          if (avaterSrc) {
            ctx.drawImage(avaterSrc, left, 35, width + 25, 180);  //参数为:图片,左,上,宽,高
            ctx.setFontSize(14);
            ctx.setFillStyle('#fff');
            ctx.setTextAlign('left');
          }
    
          //商品名称
          if (cardInfo.Name) {
            const CONTENT_ROW_LENGTH = 32; // 正文 单行显示字符长度
            let [contentLeng, contentArray, contentRows] = that.textByteLength(cardInfo.Name, CONTENT_ROW_LENGTH);
    
            ctx.setFontSize(14);
            ctx.setFillStyle('#000');
            if (contentLeng < 33) {
              ctx.setTextAlign('center');
              ctx.fillText(cardInfo.Name, windowWidth / 2, width + 33);
            } else {
              ctx.setTextAlign('left');
              let contentHh = 22 * 1;
              for (let m = 0; m < contentArray.length; m++) {
                ctx.fillText(contentArray[m], left + 10, width + 33 + contentHh * m);
              }
            }
          }
    
          //商品价格
          if (cardInfo.Price) {
            ctx.setFontSize(16);
            ctx.setTextAlign('center');
            ctx.setFillStyle("#FF4444")
            var price_width = ctx.measureText(cardInfo.Price)
            ctx.fillText(cardInfo.Price, (windowWidth - price_width.width) / 2, width + 82);
          }
    
          //商品原价
          if (cardInfo.market_price) {
            ctx.setFontSize(12);
            ctx.setTextAlign('center');
            ctx.setFillStyle("#666")
            ctx.fillText(cardInfo.market_price, (windowWidth + price_width.width) / 2 + 10, width + 82);
          }
    
    
          ctx.setFontSize(14);
          ctx.setFillStyle('#000');
          ctx.setTextAlign('left');
          ctx.fillText('长按识别小程序二维码', left + 90, width + 150);
    
          ctx.setFontSize(12);
          ctx.setFillStyle('#666');
          ctx.setTextAlign('left');
          ctx.fillText('好货要和朋友一起分享', left + 90, width + 180);
          
          //  绘制二维码
          if (codeSrc) {
            ctx.drawImage(codeSrc, left, width + 125, width / 3, width / 3)
          }
    
        }).exec()
    
        setTimeout(function() {
          ctx.draw();
          wx.hideLoading();
        }, 1000)
      }
    
      //多行文字换行
      textByteLength(text, num) {
        let strLength = 0; // text byte length
        let rows = 1;
        let str = 0;
        let arr = [];
        for (let j = 0; j < text.length; j++) {
          if (text.charCodeAt(j) > 255) {
            strLength += 2;
            if (strLength > rows * num) {
              strLength++;
              arr.push(text.slice(str, j));
              str = j;
              rows++;
            }
          } else {
            strLength++;
            if (strLength > rows * num) {
              arr.push(text.slice(str, j));
              str = j;
              rows++;
            }
          }
        }
        arr.push(text.slice(str, text.length));
        return [strLength, arr, rows] //  [处理文字的总字节长度,每行显示内容的数组,行数]
      }
    
      //点击保存到相册
      save(callback) {
        var that = this;
        wx.showLoading({
          title: '正在保存',
          mask: true,
        })
        wx.canvasToTempFilePath({
          canvasId: 'myCanvas',
          success: function(res) {
            wx.hideLoading();
            var tempFilePath = res.tempFilePath;
            wx.getSetting({
              success(res) {
                if (!res.authSetting['scope.writePhotosAlbum']) {
                  wx.authorize({
                    scope: 'scope.writePhotosAlbum',
                    success() {
                      that.save_phones(tempFilePath, callback)
                    }
                  })
                } else {
                  that.save_phones(tempFilePath, callback)
                }
              }
            })
          }
        });
      }
    
      save_phones(tempFilePath, callback) {
        wx.saveImageToPhotosAlbum({
          filePath: tempFilePath,
          success(res) {
            wx.showModal({
              content: '图片已保存到相册,赶紧晒一下吧',
              showCancel: false,
              confirmText: '好的',
              confirmColor: '#333',
              success: function(res) {
                callback(1)
              },
              fail: function(res) {
                callback(0)
              }
            })
          },
          fail: function(res) {
            wx.showToast({
              title: res.errMsg,
              icon: 'none',
              duration: 2000
            })
            callback(0)
          }
        })
      }
    }
    export {  HB};
    

    遇到的错误提示

    1、错误码:48001 api unauthorized hint:
    AccessToken错误或过期
    2、

    相关文章

      网友评论

          本文标题:小程序生成海报遇见的坑

          本文链接:https://www.haomeiwen.com/subject/tfidgqtx.html