一、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))