用canvas出海报的问题?
发布于 5 年前 作者 yongsun 9788 次浏览 来自 问答

1 获取screenHeight,打印出来是896,实际出来的图高度是808

2 同一个代码在两端不同的呈现形式:

a. 画一个圆角矩形,两边留了边,在Android上正常,在iOS直接占了全宽;

b. 给这个矩形做了alpha值,在iOS上有半透明效果,在Android上不透明.

// 保存海报
  canvasToImage(){
    this.setData({
      isHideShare: false,
    })

    
    let that = this;
    wx.showLoading({
      title: '正在保存图片..',
    });
    setTimeout(function(){
      wx.canvasToTempFilePath({
        x: that.data.off_x,
        y: that.data.off_y,
        width: that.data.canWidth,
        height: that.data.canHeight,
        destWidth: that.data.canWidth,
        destHeight: that.data.canHeight,
        canvasId: 'shareCanvas',
        success: function (res) {
          wx.saveImageToPhotosAlbum({
            filePath: res.tempFilePath,
            success(res) {
              console.log(res);
              wx.hideLoading();
              wx.showToast({
                title: '保存到相册成功',
                duration: 2500,
              })
            },
            fail(res) {
              console.log(res)
              wx.showToast({
                title: '保存到相册失败',
                icon: 'fail'
              })
              that.setData({
                isHideShare: true,
              })
            },
            complete(res) {
              console.log(res)
            }
          })
        }
      })
    }, 2000)
  },

  // 绘制分享Canvas
  drawShareCanvas: function (path) {
    // 初始化context
    console.log("drawShareCanvas")
    let ctx = wx.createCanvasContext('shareCanvas');

    console.log("screenWidth = ", this.data.screenWidth)
    console.log("screenHeight = ", this.data.screenHeight)
    // 设置位置,大小
    let canWidth = this.data.screenWidth * this.data.canRatio;
    let canHeight = this.data.screenHeight * this.data.canRatio;

    let off_y = 0;
    let qrcode_side = 80;
    let qr_area_height = 90;

    ctx.setFillStyle('white')
    ctx.fillRect(0, 0, canWidth, canHeight);

    // 绘制背景
    ctx.setGlobalAlpha(0.6)
    ctx.drawImage(path, (this.data.bgCanWidth - canWidth) / 2, (this.data.bgCanHeight - canHeight) / 2, canWidth, canHeight, 0 , off_y, canWidth, canHeight);
    

    off_y = off_y + 80;
    ctx.setGlobalAlpha(0.8)
    // 绘制card
    this.roundRect(ctx, 20,  off_y, canWidth - 40, 220, 5)
    ctx.setGlobalAlpha(1)

    // 绘制内容
    off_y = off_y + 20;
    ctx.setFillStyle('#9D9D9D')
    ctx.setFontSize(24);
    var titleText = "在你离开学校后忘记了学到的一切, 最后剩下的就是教育。";
    this.drawText(ctx, titleText, 35, off_y + 40, 100, canWidth - 75, 24);

    
    // 绘制小框框
    off_y = off_y - 20 + 220 - 20;
    ctx.setGlobalAlpha(0.8);
    this.roundRect(ctx, (canWidth - 160) / 2,  off_y, 160, 40, 5)
    ctx.setGlobalAlpha(1)

    // 绘制出自谁
    ctx.setFillStyle('#9D9D9D')
    ctx.setFontSize(18);
    titleText = "-- 爱因斯坦 ";
    ctx.fillText(titleText, (canWidth - 6 * 18) / 2, off_y + 18 + 4);

    // 绘制小程序码
    ctx.drawImage("../../images/mpcode.png", 30 ,canHeight - 100);

    // 绘制提示
    ctx.setFillStyle('black')
    ctx.setFontSize(12);
    titleText = "长按识别小程序码";
    ctx.fillText(titleText, 140, canHeight - 100);

    ctx.draw();

  },

  /**
  * 
  * [@param](/user/param) {CanvasContext} ctx canvas上下文
  * [@param](/user/param) {number} x 圆角矩形选区的左上角 x坐标
  * [@param](/user/param) {number} y 圆角矩形选区的左上角 y坐标
  * [@param](/user/param) {number} w 圆角矩形选区的宽度
  * [@param](/user/param) {number} h 圆角矩形选区的高度
  * [@param](/user/param) {number} r 圆角的半径
  */
  roundRect(ctx, x, y, w, h, r) {

    ctx.save()
    // 开始绘制
    ctx.beginPath()
    // 因为边缘描边存在锯齿,最好指定使用 transparent 填充
    // 这里是使用 fill 还是 stroke都可以,二选一即可
    ctx.setFillStyle('white')
    // ctx.setStrokeStyle('transparent')
    // 左上角
    ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5)

    // border-top
    ctx.moveTo(x + r, y)
    ctx.lineTo(x + w - r, y)
    ctx.lineTo(x + w, y + r)
    // 右上角
    ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2)

    // border-right
    ctx.lineTo(x + w, y + h - r)
    ctx.lineTo(x + w - r, y + h)
    // 右下角
    ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5)

    // border-bottom
    ctx.lineTo(x + r, y + h)
    ctx.lineTo(x, y + h - r)
    // 左下角
    ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI)

    // border-left
    ctx.lineTo(x, y + r)
    ctx.lineTo(x + r, y)

    // 这里是使用 fill 还是 stroke都可以,二选一即可,但是需要与上面对应
    ctx.fill()
    // ctx.stroke()
    ctx.closePath()
    // 剪切
    ctx.clip()
    ctx.restore()
  },

  /**
   * 绘制多行文本
   * [@param](/user/param) ctx canvas对象
   * [@param](/user/param) str 文本
   * [@param](/user/param) leftWidth 距离左侧的距离
   * [@param](/user/param) initHeight 距离顶部的距离
   * [@param](/user/param) titleHeight 文本的高度
   * [@param](/user/param) canvasWidth 文本的宽度
   * [@param](/user/param) fontSize 字体大小
   * [@returns](/user/returns) {*}
   */
  drawText: function(ctx, str, leftWidth, initHeight, titleHeight, canvasWidth, fontSize) {
    let lineWidth = 0;
    let lastSubStrIndex = 0; //每次开始截取的字符串的索引
    for (let i = 0; i < str.length; i++) {
        lineWidth += ctx.measureText(str[i]).width;
        if (lineWidth > canvasWidth) {
            ctx.fillText(str.substring(lastSubStrIndex, i), leftWidth, initHeight); //绘制截取部分
            initHeight += (fontSize * 3 / 2 + 2); //22为 文字大小20 + 2
            lineWidth = (fontSize * 3 / 2 + 2);
            lastSubStrIndex = i;
            titleHeight += (fontSize * 3 / 2 + 2);
        }
        if (i == str.length - 1) { //绘制剩余部分
            ctx.fillText(str.substring(lastSubStrIndex, i + 1), leftWidth, initHeight);
        }
    }
    // 标题border-bottom 线距顶部距离
    titleHeight = titleHeight + 10;
    return titleHeight;
  },

  downloadBackgroundImage: function (url) {
    console.log("begin draw")
    var _this = this;
    var _url = url
    wx.downloadFile({
      url: url,
      success: function (res) {
        console.log("begin download ...");
        // var path = res.tempFilePath;
        console.log("res.tempFilePath = ", res.tempFilePath);
        _this.setData({
          tempFilePath: res.tempFilePath
        })
        /****
         * 
         * 
         */
        wx.getImageInfo({
          src: _url,
          success(res) {
            console.log(res.width)
            console.log(res.height)
            _this.setData({
              bgCanWidth: res.width,
              bgCanHeight: res.height,
            })
            _this.drawShareCanvas(_this.data.tempFilePath);
          }
        })
      }, fail: function (res) {
        console.log(res)
      }
    });
  }
2 回复

你好,请提供能复现问题的简单代码片段

https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html

若认为该回答有用,给回答者点个[ 有用 ],让答案帮助更多的人

建议把你写的代码贴上来看看。

回到顶部