小程序 canvas 下载海报

let posterInfo ={
    
    cumulativeNumOfBrushedQuestions: 5
nickname: "LLA"
pictureUrl: "xW6gv2ySzEBg/132"
shareQrCode: "1645494065171.jpeg"
totalSignDays: 9
}
<yt-poster showpostflag="{
    
    {posterShow}}"
           poster='{
    
    {posterInfo}}'></yt-poster>

<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" bindlongpress="submitpostshare" 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%;
      border-radius: 12px;
      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: 311px;
    height: 497px;
    left: -667px;
    .canvas {
    
    
      width: 311px;
      height: 497px;
      background: red;
    }
  }

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,
    tabberHeight:0,
    userInfo: {
    
    }
  },
  observers: {
    
    
    poster: function(poster) {
    
    
      if(!poster){
    
    return}
      this.setData({
    
    posterInfo:poster,
        showflag:true})
      this.initCanvas()
    },
    showPost(value){
    
    
      this.setData({
    
    showflag:value})
    }

  },
  async attached() {
    
    
    // 在组件实例进入页面节点树时执行
    const {
    
     userInfo } = await app.get(['userInfo'])
    this.setData({
    
    
      userInfo: userInfo
    })
    const res = app.globalData.systemInfo;
    this.setData({
    
    
      tabberHeight: res.capsule.bottom + res.capsule.top - res.statusBarHeight,
    });
  },
  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, 311, 497) // 清空画板 // 清空画板
          ctx.fillStyle = '#FFFBF0'
          ctx.fillRect(0, 0, 311, 497)
          const image_bg = canvas.createImage()
          image_bg.src = `credit/poster.png`
          image_bg.onload = () => {
    
    

            ctx.drawImage(image_bg, 0, 0, 311, 497) // 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 16px sans-serif'
      ctx.fillStyle = '#000000'
      ctx.fillText(nickname, 78, 40) // 110, 58
      // 画头像边框
      //   ctx.beginPath()
      //   ctx.lineWidth = 3
      //   ctx.arc(53.05, 48.23,  26.52, 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(44, 40, 22, 0, 2 * Math.PI)
        ctx.clip()
        ctx.drawImage(image_avatar, 22, 18, 44,44)
        ctx.restore()
        this.drawStudyRecord(canvas, ctx)
      }
    },
    // 画科目及刷题数据
    drawStudyRecord(canvas, ctx) {
    
    
      const {
    
     totalSignDays, cumulativeNumOfBrushedQuestions, } = this.data.posterInfo
      ctx.textAlign = 'right'
      ctx.textBaseline = 'middle'
      ctx.font = '24px Helvetica'
      ctx.fillStyle = '#000000'
      //
      ctx.fillText( totalSignDays, 96, 348)//

      //
      ctx.fillText(cumulativeNumOfBrushedQuestions, 234, 348)
      // ctx.fillText('累计签到天数', 217, 524)
      this.drawDate(canvas, ctx)
      this.drawCodeImg(canvas, ctx)
    },
    drawDate(canvas, ctx) {
    
    
      var today = new Date()
      var currentyear= today.getFullYear(); // 获取当前年
      var currentmonth=today.getMonth()+1;// 获取当前月 默认0-11
      var currentday = today.getDate()
      ctx.textAlign = 'left'
      ctx.textBaseline = 'middle'
      ctx.font = '12px PingFang SC'
      ctx.fillStyle = '#FFFFFF'
      //
      ctx.fillText(currentyear+'.' +currentmonth+'.'+currentday, 34, 299)//

    },
    // 画小程序码
    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, 225, 411, 64, 64)
        ctx.restore()
        wx.canvasToTempFilePath({
    
    
          fileType: 'jpg',
          canvas: canvas,
          success(res) {
    
    
            _this.setData({
    
    
              final_url: res.tempFilePath
            })
            wx.hideLoading()
          }
        })
      }
    },
    shareImg() {
    
    
      var that =this
      wx.showShareImageMenu({
    
    
        path: this.data.final_url,
        success(res) {
    
    
          console.log(res)
          that.postSharePost()
        },
        fail(err) {
    
    
          console.warn(err)
        }
      })
    },
    postSharePost(){
    
    

    },
    close() {
    
    
      if (!this.data.maskClosable) return
      this.setData({
    
    showflag:false})
    },
    submitpostshare(){
    
    
      this.postSharePost()
    }
  }
})

猜你喜欢

转载自blog.csdn.net/sinat_36017053/article/details/123346720