wxml-to-canvas是微信封装的canvas组件能跳过麻烦的canvas定义
wxml页面
<van-overlay show="{{ sharevisble }}">
<view class="overlayBox">
<!-- 这个src是生成的海报地址 -->
<image src="{{src}}" mode="aspectFit" style="width: {{width/1.5}}px; height: {{height/1.5}}px;display:block;"></image>
<view style="width:100%;margin-top:50rpx">
<button class="save" bindtap="handleSave">保存图片至本地</button>
</view>
</view>
</van-overlay>
<!-- canvas canvas元素 宽高一定要设置好 并且让元素显示在屏幕外-->
<wxml-to-canvas width="375" height="650" class="widget" style="margin-left:105vw;" ></wxml-to-canvas>
wxss
page {
width: 100%;
height: 100%;
overflow-x:hidden;
}
json
"usingComponents": {
"wxml-to-canvas": "wxml-to-canvas"
},
js
base图片转缓存地址的方法
import { base64src } from '../../plugin/utils/base64src.js'
//⚠️海报内容和样式
const {
wxml,
style
} = require('./canvas.js');
Router({
/**
* 页面的初始数据
*/
data: {
sharevisble: false,
src: "", //生成的canvas内存地址
erweima: '',//读取得到后端给的分享码
},
//========canvas=======
//第一步渲染元素到canvas
async renderToCanvas() {
let erweima = this.data.erweima
let src = await base64src(erweima, res => {
console.log(res)
return res // 返回图片地址,直接赋值到image标签即可
});
const _wxml = wxml(src);
console.log(_wxml);
//获取canvas容器
setTimeout(() => {
//渲染到 canvas,传入 wxml 模板 和 style 对象,返回的容器对象包含布局和样式
//信息。
this.widget = this.selectComponent(".widget");
const p1 = this.widget.renderToCanvas({
wxml: _wxml,
style,
});
p1.then((res) => {
console.log("container", res.layoutBox);
this.container = res;
this.extraImage();
wx.hideLoading();
this.setData({
sharevisble: true
});
});
}, 500);
},
//第二步 canvas的图片内存地址
extraImage() {
const p2 = this.widget.canvasToTempFilePath();
p2.then((res) => {
console.log(res);
this.setData({
src: res.tempFilePath,
width: this.container.layoutBox.width,
height: this.container.layoutBox.height,
});
});
// .then(() => this.handleSave())
},
handleSave() {
console.log("保存");
const {
src
} = this.data;
const that = this;
console.log(src);
if (src) {
this.saveImageToPhotosAlbum({
filePath: src,
}).then(() => {
wx.showToast({
icon: "none",
title: "分享图片已保存至相册",
duration: 2000,
complete: function () {
that.setData({
sharevisble: false
});
},
});
});
}
},
saveImageToPhotosAlbum(option) {
return new Promise((resolve, reject) => {
wx.saveImageToPhotosAlbum({
...option,
success: resolve,
fail: reject,
});
});
},
//========canvasEND=======
两个引入的js
canvas 海报的模板样式
canvas.js
const wxml = ( erweima ) => {
return `
<view class="container" >
<view class="imgContainer">
<image class="img" src="xxxx"></image>
<image class="erweima" src="${erweima}"></image>
</view>
</view>
`
}
const style = {
container: {
width: 375,
height: 630,
},
itemBox: {
width: 80,
height: 60,
},
imgContainer: {
position: "relative",
},
img: {
width: 375,
height: 630,
},
erweima: {
width: 80,
height: 80,
position: "absolute",
bottom: 10,
left: 10,
},
}
module.exports = {
wxml,
style
}
base64转内存地址 否则不能在wxml模板渲染中显示图片
base64src.js
const fsm = wx.getFileSystemManager();
const FILE_BASE_NAME = 'tmp_base64src'; //自定义文件名
export const base64src = (base64data, cb) => {
const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || [];
if (!format) {
return (new Error('ERROR_BASE64SRC_PARSE'));
}
const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`;
const buffer = wx.base64ToArrayBuffer(bodyData);
return new Promise((resolve, reject) => {
fsm.writeFile({
filePath,
data: buffer,
encoding: 'binary',
success() {
cb(filePath);
resolve(cb(filePath))
},
fail() {
// return (new Error('ERROR_BASE64SRC_WRITE'));
reject(new Error('ERROR_BASE64SRC_WRITE'))
},
});
})
}