更优雅的在 mpvue 中使用 canvas

4,254 阅读3分钟

概述

大家对mpvue相信都不陌生,mpvue几乎抹平了我们对浏览器端和小程序端的开发差异。不过由于小程序的特性,我们终归不能将浏览器中的一些方法和功能完全移植到小程序中。比如在canvas的一些应用上,浏览器端和小程序就存在着很大的差异性。而本文主要介绍一种更加优雅的方式来使用小程序的canvas,尽可能的抹平这种差异性。这得益于mpvue所提供的强大功能。

在此之前您可以通过这篇文章(将你的 Virtual dom 渲染成 Canvas)简单了解一下vnode2canvas通过vue实现canvas在浏览器端的优雅使用。

Show me the code

先来看一段mpvue中绘画canvas的代码:

<template>
  <canvas canvas-id="canvas" :style="{width: width + 'px', height: height+'px'}"></canvas>
</template>

<script>

export default {
  data () {
    return {
      width: 0,
      height: 0
    }
  },
  canvasOptions: {
    canvasId: 'canvas'
  },
  renderCanvas (h) {
    let device = wx.getSystemInfoSync()
    this.width = device.windowWidth
    this.height = device.windowHeight
    return h('view', [
      h('image', {
        props: {
          src: 'https://pic.u51.com/sfs-gateway/api/v1/download/5f7dac8228354008ae6f69f67c1c0fa410d6'
        },
        style: {
          left: 10,
          top: 10,
          width: 100,
          height: 100,
          fill: '#000',
          fontSize: 18
        }
      }),
      h('text', {
        style: {
          left: 120,
          top: 10,
          fill: '#000',
          fontSize: 18,
          width: 150,
          ellipse: true
        }
      }, 'hello mpvue!')
    ])
  }
}
</script>

更多案例: vnode2canvas

这样就可以绘制出一个canvas:

实现方式

之前我已经写过一篇文章介绍过vnode2canvas,不过那时,并没有去做支持mpvue的功能,之前实现主要是通过$watch监听vnode的变化,然后根据vnode去做canvas渲染工作。具体技术的细节,可以参考将你的 Virtual dom 渲染成 Canvas

其实mpvuevnode的转化上也是一样的。唯一不同点便是浏览器端的canvas API 和小程序存在着比较大的差异。所以为了能抹平这种差异,我们可以借鉴axios对浏览器和node端的抹平方式。也就是说可以去做一个渲染适配器,来适配不同端的渲染工作:

/**
 * adapter for browser of weixin Mini Program
 */
class RenderAdapter {
  constructor () {
    this.platform = constants.IN_WEIXIN ? 'wx' : 'browser'
  }
  renderText (instance, ctx, scrollTop) {
    let renderFn = {
      browser () {
        // todo 浏览器 canvas text 渲染
      },
      wx () {
        // todo 小程序 canvas text 渲染
      }
    }
    renderFn[this.platform]()
  }
  // ...
}

其次就是要注意小程序端的一些环境和浏览器端环境的一些区别,做一些适配性的处理。这样便可以愉快的在mpvue中更加优雅的来达到数据驱动式的canvas渲染。同时再vnode2canvas内部封装了很多小程序canvas处理机制和优化机制,来达到更高的性能和稳定性。

后记

vnode2canvas是通过virtual dom来绘制canvas,利用Vue的数据劫持,来达到数据驱动视图的目的。得益于mpvue,也可以让其应用在小程序端。其次vnode2canvas在底层通过adapter来尽可能的抹平不同端的开发差异。同时支持对canvas内部元素的事件绑定和列表滚动。也欢迎有兴趣的小伙伴一起讨论~

vnode2canvas的一些链接:

vnode2canvas 项目

mpvue 中的使用文档

浏览器端的demo