在做的小程序要增加一个将文字与图片生成图片不可修改的功能,第一次做,在网上找了不少资料。参考了wxml-to-canvas | 微信开放文档 ,又看了一些相关事例,尝试写了一下。
需要准备的文件及配置项:
1、先把代码片段下载到本地
2、创建wxcomponents目录,把代码片段中的文件拷到此目录下,并将下图的目录改成真实目录。
3、修改配置文件pages.json,找到要写此功能的路径,加上
"style": {
"app-plus": {
"titleNView": false //禁用原生导航栏
},
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationStyle": "custom",
"usingComponents":{
"wxml-to-canvas": "/wxcomponents/wxml-to-canvas/index"
}
}
4、开始写组件。注意this.widget = this.selectComponent('.widget');一定要放在onLoad页面生命周期中,不然不生效
const {
wxml,
style
} = require('./notification.js')
export default {
data() {
return {
imgSrc: '/static/img/3.png',
//最后生成的图片信息
imageData: null,
canvasWidth: 320, // 默认canvas宽高
canvasHeight: 480,
screenWidth: null, // 设备宽度
screenHeight: null, // 设备宽度
userInfo: {},
isRegister: '',
controlContent: undefined,
statusCode: undefined,
//上个页面用到的图片地址
tempFile:undefined
}
},
onLoad(option) {
this.userInfo = uni.getStorageSync('weixin-userInfo') ? JSON.parse(uni.getStorageSync('weixin-userInfo')) :{};
// 获取设备信息
wx.getSystemInfo({
success: (res) => {
this.screenWidth = res.screenWidth
this.screenHeight = 800 //高度建议计算得出或写死。如使用res.screenHeight,文字过长时无法生成
this.canvasWidth = this.screenWidth
this.canvasHeight = this.screenHeight
setTimeout(() => {
this.widget = this.selectComponent('.widget');
this.controlContent = option.controlContent;
this.tempFile = option.tempFile
this.download();
}, 1000)
}
});
},
methods: {
//生成图片
download() {
// 数字容器宽度 动态设置
setTimeout(() => {
uni.showLoading({
title: '图片生成中...'
})
this.renderToCanvas()
}, 1000)
},
renderToCanvas() {
const _wxml = wxml('test', this.tempFile, this.controlContent) //调用wxml
const _style = style(this.screenWidth, this.canvasWidth, this.canvasHeight)
setTimeout(() => {
const p1 = this.widget.renderToCanvas({
wxml: _wxml,
style: _style
})
p1.then((res) => {
uni.hideLoading()
this.saveImageToPhotosAlbum();
}).catch((err) => {
console.log('生成失败')
})
}, 100)
},
//保存图片到本地
saveImageToPhotosAlbum() {
uni.showLoading({
title: '正在保存中...'
})
const p2 = this.widget.canvasToTempFilePath()
let that = this
p2.then(result => {
let path = result.tempFilePath
uni.uploadFile({
url: this.$u.http.config.baseUrl + '/yd/img/upload',
filePath: path,
name: 'file',
formData: {
'user': 'test'
},
success: (res) => {
let data = JSON.parse(res.data)
if (data.code == 200) {
let params = {
signUrl: data.fileName,
personId: JSON.parse(uni.getStorageSync('storage_signStatus')).personId,
signUnionId: this.userInfo.openid,
}
this.$u.api.ydSignEdit(params).then(rest => {
if (rest.code == 200) {
uni.saveImageToPhotosAlbum({
filePath: path,
success: ()=> {
uni.hideLoading()
uni.showToast({
title: '保存成功,可去手机相册查看',
duration: 2000,
icon: 'none'
});
/* uni.redirectTo({
url: '../communityControl/notification?tempFile='+ this.tempFile
}); */
uni.navigateBack();
}
});
}
}).catch(error => {
uni.showToast({
title: error.msg,
duration: 2000,
icon: 'none'
});
})
}
}
});
})
}
}
}
5、写notification.js文件,必须要按照wxml-to-canvas写生成模板,不然不生效
const wxml = (name, pic, content) => `
` + content + `
`
/**
* @param {*} screenWidth 屏幕宽度
* @param {*} canvasWidth 画布宽度
* @param {*} canvasHeight 画布高度
* @param {*} numberWidth 数字宽度,动态设置
* @return {*}
*/
const style = (screenWidth, canvasWidth, canvasHeight) => {
return {
"container": {
width: canvasWidth,
height: canvasHeight,
position: 'relative',
overflow: 'hidden',
backgroundColor: '#ffffff',
padding: '30rpx 20rpx',
},
"name": {
fontSize: 20,
color: '#333',
marginLeft: canvasWidth * 0.08,
width: canvasWidth * 0.84,
height: screenWidth * 0.18,
textAlign: 'center',
},
"content": {
fontSize: 14,
color: '#333',
width: canvasWidth * 0.84,
height: screenWidth * 0.84,
marginLeft: canvasWidth * 0.08,
marginTop: canvasWidth * 0.08,
},
"pic": {
width: canvasWidth * 0.4,
height: screenWidth * 0.2,
marginTop: canvasWidth * 0.1,
marginLeft: canvasWidth * 0.35,
marginBottom: canvasWidth * 0.05,
borderRadius: screenWidth * 0.14,
overflow: 'hidden',
},
}
}
module.exports = {
wxml,
style
}