Rendering virtual DOM into canvas based on Vue plugin
mpvue vnode2canvas
使用文档请移步到这里文档
example url: demo
npm i vnode2canvas --save
First of all, you need to register vnode2Canvas
import Vue from 'vue'
import vnode2Canvas from 'vnode2Canvas'
Vue.use(vnode2Canvas)
vnode2Canvas
will render canvas by function renderCanvas
option:
export default {
// define render options
canvasOptions: {
width: window.innerWidth, // canvas width
height: window.innerHeight // canvas height
},
renderCanvas (createElement) {
// ....
}
}
after that vnode2Canvas
will register a property named renderInstance
on vue instance:
renderInstance = {
_ctx
_canvas
...
}
A rolling list based on scroller to support lazy list loading.
new Vue({
el: '#app',
data: {
dataJSON: [
// ...
]
},
methods: {
getStyle (type, i) {
return {
img: {
left: 10,
top: 10 + 110 * i,
width: 100,
height: 100,
fill: '#000'
},
title: {
left: 120,
top: 10 + 110 * i,
fill: '#000',
fontSize: 18,
width: 150,
ellipse: true
},
desc: {
left: 120,
top: 50 + 110 * i,
fill: '#999'
},
date: {
left: 120,
top: 80 + 110 * i,
fill: '#999'
}
}[type]
}
},
canvasOptions () {
return {
width: window.innerWidth,
height: window.innerHeight
}
},
renderCanvas(h) {
return h('scrollView', {
style: {
scrollHeight: this.dataJSON.length * 110,
width: window.innerWidth,
height: window.innerHeight
}
}, this.dataJSON.map((item, i) => {
return h('view',
[
h('image', {
props: {
src: item.img
},
style: this.getStyle('img', i)
}),
h('text', {
style: this.getStyle('title', i),
}, item.title),
h('text', {
style: this.getStyle('desc', i)
}, item.desc),
h('text', {
style: this.getStyle('date', i)
}, new Date().toLocaleDateString())
])
}))
}
})
Support the following events:
click
mouseup
mousedown
- to be continue...
// ...
renderCanvas(h) {
return h('view', {
on: {
click: (e, item) => {
alert('click Text')
}
}
},
'click event'
)
}
// ...
If you think write CSS in JS is not comfortable, you can also load your external CSS file through a webpack loader.
// webpack
const canvasStyleLoader = require('canvas-style-loader')
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.css$/,
// To avoid conflicts with CSS styles, you need to specify loading paths.
include: [
path.join(__dirname, './src')
],
use: {loader: 'canvasStyleLoader'}
}
]
}
};
// index.css
image {
left: 10px;
width: 100px;
height: 100px;
}
.title {
left: 120px;
width: 100px;
height: 100px;
fill: "#000";
font-size: 18px;
}
.desc {
left: 120px;
fill: '#999'
}
.date {
left: 120px;
fill: '#999'
}
import './index.css'
// ...
renderCanvas(h) {
return h('view', this.dataJSON.map((item, i) => {
return h('view', [
h('image', {
props: {
src: item.img
},
style: {
top: 10 + 110 * i
}
}),
h('text', {
class: 'title',
style: {
top: 10 + 120 * i
}
}, item.title),
h('text', {
class: 'desc',
style: {
top: 50 + 120 * i
}
}, item.desc),
h('text', {
class: 'date',
style: {
top: 80 + 110 * i,
}
}, new Date().toLocaleDateString())
])
}))
}