wxml-to-canvas的一些使用心得
一、wxml-to-canvas的引入
- 在当前目录的控制台上输入如下代码:
npm install --save wxml-to-canvas
-
点击微信小程序左上角的《工具》->构建npm
注意:若项目之前没有使用过npm管理依赖是无法构建npm的,需要在项目根目录的控制台输入如下代码初始化npm工程。
npm init
-
引入该组件
"usingComponents": { "wxml-to-canvas": "../../miniprogram_npm/wxml-to-canvas" }
-
使用该组件
<wxml-to-canvas class="widget" width="375" height="550"></wxml-to-canvas>
注意点:
-
class属性用来标识该组件,可通过设置不同的值来创建不同的wxml-to-canvas组件实例
//在页面js文件中获取该组件实例 onload:function() { this.widget = this.selectComponent('.widget') }
-
上面的语句this.widget = this.selectComponent('.widget')是完成widget对象初始化的,但canvas生成是需要一定时间的,onload函数中widget对象还没有初始化完毕就去调用this.widget.renderToCanvas({wxml,style})将wxml模板和wxss样式绘制到canvas上 的话,会导致页面报如下错:
解决办法:
进行延迟,给含有this.widget.renderToCanvas({wxml,style})的代码块加一个定时器,500毫秒后再执行,之后就OK了
-
width和height的值不能省略。
-
二、wxml-to-canvas的避坑
-
传入this.widget.renderToCanvas中的参数名必须是wxml和style,不能是其他的。不然会报如下错误:
实际上可通过传入一个对象来完成传入不同的参数名,只要保证键的名称是wxml和style即可,如下所示:
this.widget.renderToCanvas({wxml:secondWxml,style:secondStyle})
-
每个元素都必须指定 width 和 height 属性,否则会导致布局错误。
-
wxml-to-canvas组件无法引入背景图,但实际上微信官方文档中的示例是可以引入背景图的。
打开官方的示例代码,然后在node_modules/wxml-to-canvas/miniprogram_dist/index.js 找到async drawImage(img, box, style) 函数,与wxml-to-canvas组件的同一个文件做对比可发现wxml-to-canvas多了很多莫名其妙的代码。
这些代码暂不说有什么用,却会导致wxml-to-canvas无法引入背景图,所以直接将官方的示例代码有关这个drawImage函数的代码粘贴覆盖掉wxml-to-canvas的drawImage函数。
官方示例代码中的drawImage函数如下:
async drawImage(img, box, style) { await new Promise((resolve, reject) => { const ctx = this.ctx const canvas = this.canvas const { borderRadius = 0 } = style const { left: x, top: y, width: w, height: h } = box ctx.save() this.roundRect(x, y, w, h, borderRadius, false, false) ctx.clip() const Image = canvas.createImage() Image.onload = () => { ctx.drawImage(Image, x, y, w, h) ctx.restore() resolve() } Image.onerror = () => { reject() } Image.src = img }) }
三、wxml-to-canvas的动态加载数据
由于用wxml-to-canvas绘制图片的时候是通过这个函数renderToCanvas({wxml,style})将wxml模板和wxss样式绘制到canvas上的,而我们可以通过将wxml和style包装成一个函数,通过参数完成动态显示数据。
例如:
const wxml=(word)=>{
return `
<view class="container">
<text class="text">`+word+`</text>
</view>
`
}
注意style要返回的是json格式:
const style =(width, height)=> {
return `
{
"container": {
"width":`+width+`,
"height":`+height+`,
"flexDirection":"column",
"justifyContent": "space-around",
"alignItems": "center"
},
"text": {
"width":`+width+`,
"height":37,
"fontSize":20,
"marginTop":10
}
`
}
const secondStyle = JSON.parse(style(370, 600))