小程序 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})
    }
  }
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值