概述
大家对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
的一些链接:
vnode2canvas 项目
mpvue 中的使用文档
浏览器端的demo