更優雅的在 mpvue 中使用 canvas

muwoo發表於2018-08-09

概述

大家對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:

更優雅的在 mpvue 中使用 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

相關文章