You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.0 KiB
JavaScript
118 lines
3.0 KiB
JavaScript
|
|
const xmlParse = require('./xml-parser')
|
|
const {Widget} = require('./widget')
|
|
const {Draw} = require('./draw')
|
|
const {compareVersion} = require('./utils')
|
|
|
|
const canvasId = 'weui-canvas'
|
|
|
|
Component({
|
|
properties: {
|
|
width: {
|
|
type: Number,
|
|
value: 400
|
|
},
|
|
height: {
|
|
type: Number,
|
|
value: 300
|
|
}
|
|
},
|
|
data: {
|
|
use2dCanvas: false, // 2.9.2 后可用canvas 2d 接口
|
|
},
|
|
lifetimes: {
|
|
attached() {
|
|
const {SDKVersion, pixelRatio: dpr} = wx.getSystemInfoSync()
|
|
const use2dCanvas = compareVersion(SDKVersion, '2.9.2') >= 0
|
|
this.dpr = dpr
|
|
this.setData({use2dCanvas}, () => {
|
|
if (use2dCanvas) {
|
|
const query = this.createSelectorQuery()
|
|
query.select(`#${canvasId}`)
|
|
.fields({node: true, size: true})
|
|
.exec(res => {
|
|
const canvas = res[0].node
|
|
const ctx = canvas.getContext('2d')
|
|
canvas.width = res[0].width * dpr
|
|
canvas.height = res[0].height * dpr
|
|
ctx.scale(dpr, dpr)
|
|
this.ctx = ctx
|
|
this.canvas = canvas
|
|
})
|
|
} else {
|
|
this.ctx = wx.createCanvasContext(canvasId, this)
|
|
}
|
|
})
|
|
}
|
|
},
|
|
methods: {
|
|
async renderToCanvas(args) {
|
|
const {wxml, style} = args
|
|
const ctx = this.ctx
|
|
const canvas = this.canvas
|
|
const use2dCanvas = this.data.use2dCanvas
|
|
|
|
if (use2dCanvas && !canvas) {
|
|
return Promise.reject(new Error('renderToCanvas: fail canvas has not been created'))
|
|
}
|
|
|
|
ctx.clearRect(0, 0, this.data.width, this.data.height)
|
|
const {root: xom} = xmlParse(wxml)
|
|
|
|
const widget = new Widget(xom, style)
|
|
const container = widget.init()
|
|
this.boundary = {
|
|
top: container.layoutBox.top,
|
|
left: container.layoutBox.left,
|
|
width: container.computedStyle.width,
|
|
height: container.computedStyle.height,
|
|
}
|
|
const draw = new Draw(ctx, canvas, use2dCanvas)
|
|
await draw.drawNode(container)
|
|
|
|
if (!use2dCanvas) {
|
|
await this.canvasDraw(ctx)
|
|
}
|
|
return Promise.resolve(container)
|
|
},
|
|
|
|
canvasDraw(ctx, reserve) {
|
|
return new Promise(resolve => {
|
|
ctx.draw(reserve, () => {
|
|
resolve()
|
|
})
|
|
})
|
|
},
|
|
|
|
canvasToTempFilePath(args = {}) {
|
|
const use2dCanvas = this.data.use2dCanvas
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const {
|
|
top, left, width, height
|
|
} = this.boundary
|
|
|
|
const copyArgs = {
|
|
x: left,
|
|
y: top,
|
|
width,
|
|
height,
|
|
destWidth: width * this.dpr,
|
|
destHeight: height * this.dpr,
|
|
canvasId,
|
|
fileType: args.fileType || 'png',
|
|
quality: args.quality || 1,
|
|
success: resolve,
|
|
fail: reject
|
|
}
|
|
|
|
if (use2dCanvas) {
|
|
delete copyArgs.canvasId
|
|
copyArgs.canvas = this.canvas
|
|
}
|
|
wx.canvasToTempFilePath(copyArgs, this)
|
|
})
|
|
}
|
|
}
|
|
})
|