2020-04-05

微信小程序-fix ca...

写在前面

  • 大家应该都知道过,在微信小程序中,canvas等原生组件的层级是最高的,页面中无论你设置多大的z-index都无法覆盖在其之上,这就可能会产生一些问题
  • 就像这样
    • canvas顶层问题截图
    • 柱状图是用canvas画的,它置于了我的tooltip之上。【这看起来真是一个可怕的问题

解决问题

  • 微信官方提供了cover-view原生组件,覆盖在原生组件之上的文本视图
  • 微信官方提供了将canvas转化为图片的方式–wx.canvasToTempFilePath,这样就可以”降级“

方法一:cover-view

  • 将tooltip用cover-view改写,效果如下
    • cover-view version0.1 截图
    • 看上去,是解决了我们的问题,且tooltip后的灰色背景不能滑动了,【妈耶,好棒!
    • 但是,这产生了一个:当文本超出tooltip宽度时,scroll-y: auto,失效了,溢出部分被直接截取
    • 罪魁祸首就是它
      • cover内置样式
    • 那我们可以:
      • 在tooltip分段内容中加上
        1
        2
        3
        .modal-layer-content-rule {
        white-space: pre-wrap;
        }
      • 在内容wrapper中加上
        1
        2
        3
        .modal-layer-content {
        overflow: scroll;
        }
    • 完美解决
      • cover-view解决图

        方法二:wx.canvasToTempFilePath

  • 首先我们要做的就是将网络图片绘制进canvas,官方关于canvas类型有两种
    两种canvas类型
  • 新canvas 2D接口尝试
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    const query = wx.createSelectorQuery().in(this)
    query.select('#myCanvas')
    .fields({ node: true, size: true })
    .exec((res) => {
    const canvas = res[0].node
    const ctx = canvas.getContext('2d')
    const img = canvas.createImage()
    img.onload = () => {
    ctx.drawImage(img, 0, 0, 100, 100)
    }
    img.src = 'https://p0.meituan.net/myvideodistribute/0990cc2062e81ab6cc11fd8690f8755042005.jpg'
    // 这种方式获取canvas区域隐含的像素数据
    console.log(ctx.getImageData(0, 0, 150, 100).data)
    })
    1
    <canvas type="2d" id="myCanvas" canvas-id="myCanvas"></canvas>
  • 运行截图canvas2d 运行截图
  • 第二种旧canvas
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    const ctx = wx.createCanvasContext('myCanvas')
    wx.getImageInfo({
    src: 'https://p0.meituan.net/myvideodistribute/0990cc2062e81ab6cc11fd8690f8755042005.jpg',
    success: function (res) {
    console.log('res', res)
    const poster = res.path
    ctx.drawImage(poster, 0, 0, 150, 100)
    ctx.draw()
    }
    })
    // 这种方式获取canvas区域隐含的像素数据
    wx.canvasGetImageData({
    canvasId: 'myCanvas',
    x: 0,
    y: 0,
    width: 150,
    height: 100,
    success(res) {
    console.log(res.width) // 150
    console.log(res.height) // 100
    console.log(res.data instanceof Uint8ClampedArray) // true
    console.log(res.data) // 150 * 100 * 4
    console.log(res.data.length) // 150 * 100 * 4
    }
    })
    1
    <canvas id="myCanvas" canvas-id="myCanvas"></canvas>
  • 运行截图旧canvas
  • 虽然两种方法,都能实现将网络图片绘制进canvas,但新版的进行了createImage,将其打印的话,其实就是新建了一个img标签,并将img标签的东西绘制进canvas
    • img console
    • 为什么微信官方会仅支持以下方式进行新版canvas2d 图片的绘制,考虑是什么?
    • 经典报错
  • 现在我们要将canvas的内容导成图片,同样分成新旧两版
  • 主要思路都是:在wxml中,如果canvas绘制图片没有完成,则显示canvas内容,绘制完成后,就利用canvasToTempFilePath,将图层内容生成指定大小图片,显示image
    • canvas2d
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      const that = this
      const query = wx.createSelectorQuery().in(this)
      query.select('#myCanvas')
      .fields({ node: true, size: true })
      .exec((res) => {
      const canvas = res[0].node
      const ctx = canvas.getContext('2d')
      const img = canvas.createImage()
      console.log('img', img)
      img.onload = () => {
      ctx.drawImage(img, 0, 0, 100, 100)
      wx.canvasToTempFilePath({
      x: 0,
      y: 0,
      width: 100,
      height: 100,
      destWidth: 100,
      destHeight: 100,
      canvas: canvas,
      success(res) {
      that.setData({
      imgPath: res.tempFilePath
      })
      },
      fail(err) {
      console.log('err', err)
      }
      })
      }
      img.src = 'https://p0.meituan.net/myvideodistribute/0990cc2062e81ab6cc11fd8690f8755042005.jpg'
      // 这种方式获取canvas区域隐含的像素数据
      console.log(ctx.getImageData(0, 0, 100, 100).data)
      })
      1
      2
      <canvas wx:if="{{!imgPath}}" type="2d" id="myCanvas" canvas-id="myCanvas" style="width: 330px;height: 340px;"></canvas>
      <image wx:else src="{{imgPath}}" style="width: 330px;height: 340px;" />
      • canvas2d 需要踩得坑是:它的官方文档🙃
        • canvas2d 转图片误导
        • 尝试下来,会
          • ctx.draw报错
        • 那我们可以继续往下看
          • canvas2d tempath正确实力这才是符合我们需要
      • 运行截图
        • canvas2d运行截图
    • 旧版canvas
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      const ctx = wx.createCanvasContext('myCanvas')
      const that = this
      wx.getImageInfo({
      src: 'https://p0.meituan.net/myvideodistribute/0990cc2062e81ab6cc11fd8690f8755042005.jpg',
      success: function (res) {
      console.log('res', res)
      const poster = res.path
      ctx.drawImage(poster, 0, 0, 150, 100)
      ctx.draw(false, () => {
      wx.canvasToTempFilePath({
      x: 0,
      y: 0,
      width: 100,
      height: 100,
      destWidth: 100,
      destHeight: 100,
      canvasId: "myCanvas",
      success(res) {
      that.setData({
      imgPath: res.tempFilePath
      })
      console.log(res.tempFilePath)
      },
      fail(err) {
      console.log('err', err)
      }
      })
      })
      // 这种方式获取canvas区域隐含的像素数据
      wx.canvasGetImageData({
      canvasId: 'myCanvas',
      x: 0,
      y: 0,
      width: 150,
      height: 100,
      success(res) {
      console.log(res.width) // 150
      console.log(res.height) // 100
      console.log(res.data instanceof Uint8ClampedArray) // true
      console.log(res.data) // 150 * 100 * 4
      console.log(res.data.length) // 150 * 100 * 4
      }
      })
      }
      })
      1
      2
      <canvas wx:if="{{!imgPath}}" id="myCanvas" canvas-id="myCanvas" style="width: 330px;height: 340px;"></canvas>
      <image wx:else src="{{imgPath}}" style="width: 330px;height: 340px;" />
      • 运行截图
        • 旧版canvas运行截图

          写在后面

  • 感谢Skady宝贝在探讨问题中给予的帮助,欢迎大家去github找她玩👈
  • 祝大家多多发财