小程序 canvas 分享组件

<view catchtap="close" class="c-dialog-mask" wx:if="{
    
    {showflag&& mask}}" ></view>
<block  wx:if="{
    
    {showflag}}">
    <view class="final-img-content" catchtap="close" wx:if="{
    
    {showflag}}"  catchtouchmove="touchMove">
        <image show-menu-by-longpress class="final-img" src="{
    
    {final_url}}" />
    </view>
    <view class="canvas-box">
        <canvas class="canvas" id="posterCanvas" type="2d"></canvas>
      </view>
    <!-- <view class="save-btn" bind:tap="shareImg">保存海报</view> -->
</block>

.c-dialog-mask {
    
    
  position: fixed;
  z-index: 999;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  width: 100vw;
  height: 100vh;
}

  .final-img-content {
    
    
    position: fixed;
    width: 100vw;
    height: 100vh;
    top: 50%;
    left: 50%;
    z-index: 1000;
    transform: translateX(-50%) translateY(-50%);
    .final-img {
    
    
      position: absolute;
      width: 311px;
      height: 497px;
      left: 50%;
      top:50%;
      margin-top: -249px;
      margin-left: -155px;
    }
  }
//   .save-btn {
    
    
//     position: absolute;
//     bottom: 0;
//     left: 0;
//     width: 686rpx;
//     height: 92rpx;
//     background: var(--color-theme);
//     border-radius: 46rpx;
//     line-height: 92rpx;
//     font-size: 36rpx;
//     font-weight: 500;
//     color: #ffffff;
//     text-align: center;
//     position: fixed;
//     bottom: calc(constant(safe-area-inset-bottom));
//     bottom: calc(env(safe-area-inset-bottom));
//     left: 50%;
//     transform: translateX(-50%);
//   }
  .canvas-box {
    
    
    position: absolute;
    top: 0;
    width: 375px;
    height: 667px;
    left: -667px;
    .canvas {
    
    
      width: 375px;
      height: 667px;
    }
  }

{
    
    
    "component": true,
    "usingComponents": {
    
    }
}



```javascript
const app = getApp()
Component({
  // 声明组件属性及默认值
  properties: {
    // 点击mask关闭
    maskClosable: {
      type: Boolean,
      value: true
    },
    mask: {
      // 是否需要 遮罩层
      type: Boolean,
      value: true
    },
    poster: {
      type: Object,
      value: {}
    },
    showpostflag:{
      type: Boolean,
      value: false
    },
  },
  data: {
    posterInfo:null,
    final_url:'',
    showflag:false
  },
  observers: {
    poster: function(poster) {
      if(!poster){return}
      this.setData({posterInfo:poster,
        showflag:true})
      this.initCanvas()
    },
    showPost(value){
      this.setData({showflag:value})
    }

  },
  methods: {
    // 初始化背景
    initCanvas() {
      wx.showLoading({ title: '玩命加载中', mask: true })
      const _this = this
      const query = wx.createSelectorQuery().in(this)
      query
        .select('#posterCanvas')
        .fields({ node: true, size: true })
        .exec(res => {
          const canvas = res[0].node
          const ctx = canvas.getContext('2d')
          const system = app.globalData.systemInfo
          const dpr = system.pixelRatio
          canvas.width = res[0].width * dpr
          canvas.height = res[0].height * dpr
          ctx.scale(dpr, dpr)
          ctx.clearRect(0, 0, 375, 667) // 清空画板 // 清空画板
          ctx.fillStyle = '#FFFBF0'
          ctx.fillRect(0, 0, 375, 667)
          const image_bg = canvas.createImage()
          image_bg.src = `https://basic/KUAIJI.png`
          image_bg.onload = () => {
    
    

            ctx.drawImage(image_bg, 0, 0, 375, 667)
            ctx.drawImage(image_bg, 54, 230, 267, 247)
            _this.drawAvatarName(canvas, ctx)
          }
        })
    },
    // 画用户头像和昵称
    drawAvatarName(canvas, ctx) {
    
    

      let {
    
     nickname, pictureUrl } = this.data.posterInfo
      ctx.textAlign = 'left'
      ctx.textBaseline = 'middle'
      ctx.font = 'normal 500 22px sans-serif'
      ctx.fillStyle = '#000000'
      ctx.fillText(nickname, 110, 200)
      // 画头像边框
      ctx.beginPath()
      ctx.lineWidth = 3
      ctx.arc(76, 198, 22, 0, 2 * Math.PI)
      ctx.strokeStyle = '#000000'
      ctx.stroke()
      const image_avatar = canvas.createImage()
      image_avatar.src = pictureUrl.replace('https://thirdwx.qlogo.cn', 'https://wx.qlogo.cn')
      image_avatar.onload = () => {
    
    
        ctx.save()
        ctx.arc(73, 198, 22, 0, 2 * Math.PI)
        ctx.clip()
        ctx.drawImage(image_avatar, 54, 176, 44,44)
        ctx.restore()
        this.drawStudyRecord(canvas, ctx)
      }
    },
    // 画科目及刷题数据
    drawStudyRecord(canvas, ctx) {
    
    
      const {
    
     totalSignDays, cumulativeNumOfBrushedQuestions } = this.data.posterInfo
      ctx.textAlign = 'center'
      ctx.textBaseline = 'middle'
      ctx.font = 'Helvetica'
      ctx.fillStyle = '#000000'
      // 累计刷题
      ctx.fillText(cumulativeNumOfBrushedQuestions, 99, 489)
      ctx.fillText('累计刷题数量', 73, 524)
      // 备战天数
      ctx.fillText(totalSignDays, 237, 489)
      ctx.fillText('累计签到天数', 217, 524)
      // 画科目
      ctx.textAlign = 'left'
      ctx.font = 'normal 400 14px sans-serif'
      this.drawCodeImg(canvas, ctx)
    },

    // 画小程序码
    async drawCodeImg(canvas, ctx) {
    
    
      const _this = this
      // 画小程序码边框
      //   ctx.beginPath()
      //   ctx.lineWidth = 4
      //   ctx.arc(304, 596, 53, 0, 2 * Math.PI)
      //   ctx.strokeStyle = '#000000'
      //   ctx.stroke()
      const image_code = canvas.createImage()
      image_code.src = _this.data.posterInfo.shareQrCode
      image_code.onload = () => {
    
    
        ctx.save()
        ctx.beginPath()
        // ctx.arc(304, 596, 51, 0, 2 * Math.PI)
        // ctx.clip()
        ctx.drawImage(image_code, 259, 569, 63, 63)
        ctx.restore()
        wx.canvasToTempFilePath({
    
    
          fileType: 'jpg',
          canvas: canvas,
          success(res) {
    
    
            _this.setData({
    
    
              final_url: res.tempFilePath
            })
            wx.hideLoading()
          }
        })
      }
    },
    shareImg() {
    
    
      wx.showShareImageMenu({
    
    
        path: this.data.final_url,
        success(res) {
    
    
          console.log(res)
        },
        fail(err) {
    
    
          console.warn(err)
        }
      })
    },
    close() {
    
    
      if (!this.data.maskClosable) return
      this.setData({
    
    showflag:false})
    }
  }
})

猜你喜欢

转载自blog.csdn.net/sinat_36017053/article/details/123072725
今日推荐