概述
大家对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
其实mpvue在vnode的转化上也是一样的。唯一不同点便是浏览器端的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的一些链接: