微信小程序分享海报

包括有功能:多张商品图排版、保存海报到本地、预览转发海报、转发小程序
图片包括了功能

wxml文件

<!-- 分享海报弹窗 -->
<view class="mask" bindtap='formatHide' wx:if="{{showPostersStatus}}"></view>
<view class="share_con" animation="{{animationData}}" wx:if="{{showPostersStatus}}">
  <!-- 海报区域 -->
  <view class="poster_area" style="height:{{ctxh}}rpx">
    <view class='dialog-close2' bindtap='formatHide'><image src='{{dialogClose2}}'></image></view>
    <image src="{{shareImgPath}}"  wx:if='{{drawposters}}'></image>
  </view>
  <!-- 按钮区域 -->
  <view class="btn_area">
    <view class='dialog-close' bindtap='formatHide'><image src='{{dialogClose}}'></image></view>
    <view class="set_type">
      <text>选择排版</text>
      <view class="{{tabobj.tabbool==1?'picTabs':''}}" data-tab='1' data-imgnum="0" data-ctxdiff="0" bindtap="picTab">单张图</view>
      <view wx:if="{{goods.imgs.length>1}}" class="{{tabobj.tabbool==2?'picTabs':''}}" data-tab='2' data-imgnum="4" data-ctxdiff="115" bindtap="picTab">四张图</view>
    </view>
    <view class="posters_btn">
      <button wx:if="{{!openset}}" class="posters_btn1" bindtap="savePosters"><image src="{{posters_icon1}}"></image> 保存海报</button>
      <button wx:if="{{openset}}" class="posters_btn1" bindtap="openSet" bindopensetting="openSet"><image src="{{posters_icon1}}"></image> 保存海报</button>
      <button class="posters_btn2" open-type="share"><image src="{{posters_icon2}}}"></image> 转发小程序</button>
      <view class="posters_btn3" bindtap='imgYu' data-src="{{shareImgPath}}}"><image src="{{posters_icon3}}}"></image> 转发海报</view>
    </view>
    <view class="bottom_tip">※专属链接,转发可锁粉</view>
  </view>
</view>
<canvas canvas-id='share' style="width:{{ctxw}}px;height:{{ctxh}}px;position:fixed;left: -10000px;background:#fff;" hidden='{{canvasHidden}}'></canvas> 
<!-- 分享海报弹窗end -->

js文件

const wxGetImageInfo = promisify(wx.getImageInfo)
function promisify( api){
    return (options, ...params) => {
      return new Promise((resolve, reject) => {
        const extras = {
          success: resolve,
          fail: reject
        }
        api({ ...options, ...extras }, ...params)
      })
    }
}
Page({
  data: {
    showModalStatus: false,
    showParaModalStatus: false,
    showShareStatus: false,
    showPlaybillStatus: false,
    scrollStatus: true,
    userInfo:{},
    goods_item: {},
    goods: {},
    goods_list: {},
    animationData: {},
    dialogClose: app.globalData.Domain + 'img/common/dialog_close.png?' + random,
    dialogClose2: app.globalData.Domain + 'img/common/dialog_close2.png?' + random,
    share_icons: app.globalData.Domain + 'img/common/share_icon.png?' + random,
    posters_icon1: app.globalData.Domain + 'img/common/posters_icon1.png?' + random,
    posters_icon2: app.globalData.Domain + 'img/common/posters_icon2.png?' + random,
    posters_icon3: app.globalData.Domain + 'img/common/posters_icon3.png?' + random,
    posters_pic1: app.globalData.Domain + 'img/goods/posters_pic1.png?' + random,
    posters_pic2: app.globalData.Domain + 'img/goods/posters_pic2.png?' + random,
    avatarUrl_default: app.globalData.Domain + 'img/goods/post_logo.png?' + random,
    qrcode_default: app.globalData.Domain + 'img/goods/codeImg.jpg?' + random,
    is_show_service: false,
    canvasHidden: true,
    tabobj: {
      tabbool: 1,
      imgnum: 0,
      ctxdiff: 0
    },
    ctxw: 483,
    ctxh: 755,
    shareImgPath: '',
    backIndex: false,
    drawposters: false,
    openset: false,
    showPostersStatus: false, //分享海报
    userInfos: "",
  },

/**
 * 展示海报
 */
  sharePosters(e) {
    this.setData({
      scrollStatus: false,
      shareImgPath: ''
    })
    var animation = wx.createAnimation({
      duration: 300,
      timingFunction: "linear",
      delay: 0
    })
    this.animation = animation
    animation.translateY(500).step()

    this.setData({
      animationData: animation.export(),
      showPostersStatus: true
    })

    setTimeout(function () {
      animation.translateY(0).step()
      this.setData({
        animationData: animation.export(),
        showPostersStatus: true
      })

    }.bind(this), 100)
    this.saveImg(this.data.tabobj);
  },
    /**
   * 隐藏海报
   */
  formatHide: function (e) {
    this.setData({
      showPostersStatus: false, //分享海报
    })
  },
  // 选择排版切换
  picTab(e) {
    let tabbool = e.currentTarget.dataset.tab;
    let imgnum = e.currentTarget.dataset.imgnum;
    let ctxdiff = e.currentTarget.dataset.ctxdiff;
    let tabobj = {
      tabbool,
      imgnum,
      ctxdiff
    }
    this.saveImg(tabobj)
  },
  // 图片预览
  imgYu() {
    if (this.data.shareImgPath) {
      Promise.all(
        [wxGetImageInfo({
          src: this.data.shareImgPath
        })]
      ).then((res)=>{
        //图片预览
        wx.previewImage({ 
          current: res[0].path, // 当前显示图片的http链接
          urls: [res[0].path],
          success() {
            // wx.showToast({
            //   title: '长按发送给朋友',
            // })
          }
        })
      })
    } else {
      util.showErrorToast('请等绘制完成')
    }
  },
  /**
   * 分享
   */
  onShareAppMessage(res) {
    wx.showShareMenu({
      withShareTicket: true
    })
    let userInfo = wx.getStorageSync('userInfo');
    let sellerId = userInfo.seller_id || 0;
    let path = `/pages/goods/detail/detail?item_id=${this.data.item_id}&goods_id=${this.data.goods_id}&backIndex=true&share_seller_id=${sellerId}`;
    
    return {
      title: this.data.goods_item.title,
      path: path,
      imageUrl: this.data.goods.imgs[0].big,
      success(shareTickets) {
        console.log(path)
      }
    }
  },
  /**
   * 查看是否授权&&获取用户信息
   */
  getUserInfo() {
    let _this = this
    return new Promise((resolve, reject) => {
      // 查看是否授权
      wx.getSetting({
        success(res) {
          if (res.authSetting['scope.userInfo']) {
            wx.getUserInfo({
              success(res){
                let userInfos = res.userInfo
                _this.setData({
                  userInfos
                })
                _this.sharePosters()
                return resolve(res)
              },  
              fail(res){
                util.showErrorToast('信息获取失败!')
              }
            })
          } else {
            util.showErrorToast('请先授权!!')
          }
        },
        fail(err){
          util.showErrorToast('请先授权!!')
          return false
        }
      })
    })
  },
  // 获取图片信息
  getImageInfo(img) {
    var imgarr = [];
    wx.getImageInfo({
      src: img,
      success: (res)=>{
        imgarr = [res.width, res.height]
        return imgarr
      },
      fail: (res)=>{
        console.log(res)
      }
    })
  },
  /**
   * 文字处理
   */
  fillTextLineBreak(ctx, text, y, lw, lh, lineNum, ellipsis) {
    let i = 0;
    let n = 0;
    let r = -1;
    while (i < text.length) {
      while (ctx.measureText(text.substring(n, i)).width < lw && i < text.length) {
        i++
      }
      r++
      if(lineNum == r) {
        let texts = text.substring(n, i)
        let measureW = ctx.measureText(text.substring(n, i)).width
        let obj = {
          text: ellipsis ? measureW > lw ? texts + '...':texts : texts,
          y: y + lh * r
        }
        return obj
      }
      n = i
    }
  },
  product_imgs(imgnums, product_img) {
    let product_img_arr = [];
    for(let i = 1; i< imgnums; i++) {
      if (product_img[i]) {
        product_img_arr.push(
          wxGetImageInfo({
            src: product_img[i].big
          })
        )
      }
    }
    return product_img_arr
  },
  /**
   * 获取图片
   */
  getImg(callback, tabobj) {
    let imgnums = tabobj ? tabobj.imgnum || 0 : 0
    Promise.all([
      wxGetImageInfo({
        src: this.data.posters_pic1
      }),
      wxGetImageInfo({
        src: this.data.posters_pic2
      }),
      wxGetImageInfo({
        src: this.data.userInfos.avatarUrl || this.data.avatarUrl_default
      }),
      wxGetImageInfo({
        src: this.data.qrcode_default
      }),
      wxGetImageInfo({
        src: this.data.goods.imgs[0].big
      }),
      ...(this.product_imgs(imgnums, this.data.goods.imgs)),
    ]).then(res=>{
      wx.showLoading({
        title: '绘制中......',
      })
      callback && callback(res)
    }).catch(err=>{
        console.log(`报错${err}`);
    })
  },
  /**
 * 画图
 */
  drawImages(ctx, imgInfos, tabobj, scale_img){
    let [
      { path: plantsImg1 },
      { path: plantsImg2 },
      { path: avatarUrl },
      { path: qrcode_default },
      { path: product_img0 }
    ] = imgInfos
    let tabbool = tabobj ? tabobj.tabbool || 1 : 1
    let imgnums = tabobj ? tabobj.imgnum || 0 : 0
    let ctxdiff = tabobj ? tabobj.ctxdiff || 0 : 0
    ctx.drawImage(plantsImg1, 0, 0, ctx.width, 544 / scale_img);
    ctx.drawImage(plantsImg2, 33 / scale_img, ctx.height - 80, 690 / scale_img, 62 / scale_img);
    ctx.drawImage(qrcode_default, 380, 480 + (ctxdiff | 0), 85, 85);
    ctx.drawImage(product_img0, 20, 160, 690 / scale_img, 460 / scale_img);
    if (tabbool == 2) {
      for (let i = 1; i < imgnums; i++) {
        imgInfos[i + 4] && ctx.drawImage(imgInfos[i + 4].path, 20 + (220 / scale_img + 10) * (i - 1), 470, 220 / scale_img, 147 / scale_img)
      }
    };
    ctx.arc(60, 95, 40, 0, 2 * Math.PI, false);
    ctx.clip();
    ctx.drawImage(avatarUrl, 20, 55, 80, 80);
    ctx.restore();
  },
  saveImg(tabobj) {
    this.getImg(res=>{
      let imgInfos = res;
      let ctxdiff = tabobj ? tabobj.ctxdiff || 0 : 0
      let ctxh = 755 + (ctxdiff|0);
      let ctxw = this.data.ctxw
      var that = this;
      let goodsname = this.data.goods_item.title;
      let nickName = this.data.userInfos.nickName;
      // let product_img = this.data.goods.imgs;
      // let qrcode_default = this.data.qrcode_default; // 二维码
      let oldprize = '¥' + this.data.shop_price;
      let nowprize = '¥'+ this.data.price;
      this.setData({
        canvasHidden: false,
        drawposters: false
      })
      let timers = setTimeout((res)=>{
        if (this.data.shareImgPath) {
          return false
        } else {
          wx.hideLoading()
          util.showErrorToast('网络不好,重绘!')
        }
      }, 5500)
      let ctx = wx.createCanvasContext('share');
      this.setData({
        ctxh,
        tabobj
      })
      ctx.height = ctxh;
      ctx.width = ctxw;
      let scale_img = 1.55; //缩放比例
      ctx.save();
      ctx.beginPath(); 
      ctx.setFillStyle('#fff')
      ctx.fillRect(0, 0, ctxw, ctxh);
      this.drawImages(ctx, imgInfos, tabobj, scale_img);
      ctx.setFontSize(25);
      ctx.setFillStyle('white');
      ctx.fillText(nickName || '你好大象', 110, 90);
      ctx.setFontSize(18);
      ctx.fillText('邀请您享受大象居家优惠', 110, 115);
      ctx.setFontSize(20);
      ctx.setFillStyle('black');
      let fillTextObj1 = this.fillTextLineBreak(ctx, goodsname, 495 + (ctxdiff|0), 285, 25, 0);
      let fillTextObj2 = this.fillTextLineBreak(ctx, goodsname, 495 + (ctxdiff|0), 275, 25, 1, 1);
      ctx.fillText(fillTextObj1.text, 20, fillTextObj1.y);
      fillTextObj2 && ctx.fillText(fillTextObj2.text, 20, fillTextObj2.y);
      ctx.setFillStyle('#ff2323');
      ctx.fillText(nowprize, 20, 575+(ctxdiff|0));
      let nowprizeW = ctx.measureText(nowprize).width;
      if (oldprize != nowprize && nowprize < oldprize) {
        ctx.setFillStyle('#a8a8a8');
        ctx.setFontSize(16);
        ctx.fillText(oldprize, 30 + nowprizeW, 575 + (ctxdiff|0));
        let oldprizeW = ctx.measureText(oldprize).width;
        ctx.moveTo(30 + nowprizeW, 570 + (ctxdiff | 0));
        ctx.lineTo(30 + nowprizeW + oldprizeW, 570 + (ctxdiff | 0));
        ctx.setStrokeStyle('#a8a8a8')
        ctx.stroke();
      }
      ctx.setFontSize(14);
      ctx.setFillStyle('#111');
      ctx.fillText('长按识别二维码', 365, 585 + (ctxdiff|0));
      ctx.restore();
      //把画板内容绘制成图片,并回调 画板图片路径
      ctx.draw(false, () => {
        setTimeout(() => {
          wx.canvasToTempFilePath({
            x: 0,
            y: 0,
            width: ctx.width,
            height: ctx.height,
            destWidth: ctx.width * 2,
            destHeight: ctx.height * 2,
            fileType: 'jpg',
            canvasId: 'share',
            success: (res) => {
              if (!res.tempFilePath) {
                wx.showModal({
                  title: '提示',
                  content: '图片绘制中,请稍后重试',
                  showCancel: false
                })
              }
              this.setData({
                shareImgPath: res.tempFilePath, 
                ctxh,
                tabobj,
                drawposters: true
              })
              wx.hideLoading()
            },
            fail: (err) => {
              console.log(`${new Date} 报错${err}`)
              wx.hideLoading()
            }
          })
          timers && clearTimeout(timers)
        }, 800)
      })
    }, tabobj)

  },

  // 保存分享海报
  //画板路径保存成功后,调用方法吧图片保存到用户相册
  savePosters() {
    wx.saveImageToPhotosAlbum({
      filePath: this.data.shareImgPath,
      //保存成功失败之后,都要隐藏画板,否则影响界面显示。
      success: (res) => {
        wx.hideLoading();
        this.setData({
          canvasHidden: true
        })
        wx.showModal({
          content: '保存成功',
          showCancel: false
        })
      },
      fail: (res) => {
        console.log(res)
        if (res.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || res.errMsg === "saveImageToPhotosAlbum:fail auth deny"){
          console.log("打开设置窗口");
          util.showErrorToast('请打开设置授权相册')
          this.setData({
            openset: true
          })
        }
      }
    })
  },
  openSet() {
    this.setData({ openset:false })
    wx.openSetting({
      success(settingdata) {
        if (settingdata.authSetting["scope.writePhotosAlbum"]) {
          console.log("获取权限成功,再次点击图片保存到相册")
        } else {
          console.log("获取权限失败")
        }
      },
      fail(err) {
        console.log(`报错${new Date}:${err}`)
        util.showErrorToast('请打开设置授权相册')
      }
    })
  },
  getShareCode() {
    let that = this;
    //获取分享码
    let page = 'pages/goods/detail/detail';
    let userInfo = wx.getStorageSync('userInfo');
    let sellerId = userInfo.seller_id || 0;
    //scene可自定义规则,注意长度微信有限制
    let scene = `${that.data.item_id},${that.data.goods_id},${sellerId}`;
    util.request(api.WxacodeUnlimited, {
      'page': page, 'scene': scene
    }, 'POST').then((res) => {
      if (res.code == 200) {
        that.setData({
          qrcode_default: res.data.qrcode
        });
      }
    });
  },
 onLoad: function (options) {
    var that = this;
    wx.getSystemInfo({
      success: function (res) {
        that.setData({
          scrollHeight: res.windowHeight
        });
      }
    });
    wx.showLoading({
      title: '加载中...',
    });
    let item_id = parseInt(options.item_id);
    let goods_id = parseInt(options.goods_id);
    let backIndex = options.backIndex || false;
    let share_seller_id = parseInt(options.share_seller_id) || 0;
    if (options.scene != undefined) {//扫码进入
      let scene = decodeURIComponent(options.scene);
      backIndex = true;
      let param = scene.split(',');
      item_id = param[0] || 0;
      goods_id = param[1] || 0;
      share_seller_id = param[2] || 0;
    }
    if (share_seller_id > 0) {
      app.globalData.userInfo.share_seller_id = share_seller_id;
    }
    this.setData({
      'item_id': item_id,
      'goods_id': goods_id,
      'backIndex':backIndex,
    });
    this.getGoodsInfo();
    this.getShareCode();
    // .then(()=>{
    //   this.saveImg();
    // });
    // this.getUserInfo()
    wx.hideLoading();
  },

  onShow: function () {
    // 分享
    let userInfo = wx.getStorageSync('userInfo');
    let token = wx.getStorageSync('token');
    // 页面显示
    if (userInfo && token) {
      app.globalData.userInfo = userInfo;
      app.globalData.token = token;
    }
    this.setData({
      userInfo: app.globalData.userInfo,
    });
  },
  })

wxss文件

/* 分享海报 */
.share_btn {
  position: absolute;
  width: 80rpx;
  height: 80rpx;
  top: 10rpx;
  right: 0rpx;
  border-radius: 50%;
  box-shadow: 0 0 25rpx -5rpx rgb(0, 0, 0, 0.35);
  background: transparent;
  line-height: 100%;
  padding: 0;
  margin: 0;
}
.share_con {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  z-index: 101;
}
.btn_area {
  position: absolute;
  bottom: env(safe-area-inset-bottom);
  width: 100%;
  height: 360rpx;
  background-color: #fff;
  z-index: 101;
}
.set_type {
  width: 485rpx;
  height: 60rpx;
  margin: 40rpx auto 40rpx;
}
.set_type text {
  float: left;
  line-height: 60rpx;
  font-size: 20rpx;
  color: #666;
}
.set_type view {
  float: left;
  margin-left: 30rpx;
  padding: 10rpx 25rpx;
  font-size: 32rpx;
  border: 1px solid #ccc;
  border-radius: 30rpx;
}
.set_type .picTabs {
  border: 1px solid #333;
  color: #333;
}
.posters_btn {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 500rpx;
  margin: 0 auto 40rpx;
}
.posters_btn::after {
  position: absolute;
  content: "";
  bottom: -20rpx;
  width: 100%;
  height: 1px;
  background-color: #ccc;
}
.posters_btn view,.posters_btn button  {
  display: flex;
  justify-content: space-around;
  align-items: center;
  flex-direction: column;
  height: 140rpx;
}
.posters_btn button {
  font-size: 24rpx;
  color:#333;
  background: transparent;
  line-height: 100%;
  padding: 0;
  margin: 0;
}
.posters_btn view image,.posters_btn button image {
  width: 80rpx;
  height: 80rpx;
}
.bottom_tip {
  width: 100%;
  color: #333;
  text-align: center;
}
.poster_area {
  position: absolute;
  bottom: 360rpx;
  left: 50%;
  transform: translateX(-50%);
  width: 483rpx;
  height: 755rpx;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值