这是我目前接触到的比较好用的海报插件了
官方还有wxml-to-canvas 不会用 有很多标签 样式上不去
界面化生成,可以直接布局
GitHub 地址 这个案例可以直接下载然后打开就是一个小程序,很明了的一个示例
这是作者在微信平台那么的一个贴算是
现在知道的一个无法生效的样式 一些对齐的样式无法生效
海报中的大部分元素还是要自己通过定位样式去设置位置的
关于文字居中,需要通过计算文本的长度去实现
// 用来计算根据不同的文本长度去偏移不同的量
/*
left:当前的默认忽略文本长度默认的偏移值
fontSize:文本的字体大小
length:文本长度
返回值:根据当前文本长度计算出的偏移量
*/
function countLeft(left,fontSize,length){
return left - (fontSize / 2 * length) + 'px'
}
// 如果要在画布上渲染图片的话 ,canvas不允许加载跨域资源,为了防止画布污染 哪里的画布都一样 很蛋疼
// 所有要把网络请求来的图片处理成本地地址,就不会有跨域问题了
// 直接放到项目里的图片就不用处理直接就可以用
let getImage = (url) => {
return new Promise((r,j) => {
wx.getImageInfo({
src: url,
success:(e) => {
r(e.path)
}
})
})
}
// 使用例子
async function(){
var loactionImage = await getImage('网络图片链接')
}
// 也可以直接把要用到图片直接的本地地址直接缓存到storage缓存里面
这是我的部分代码
Component({
properties: {
//属性值可以在组件使用时指定
imageDate:{
type:Object,
value:{}
},
actions:{
type:Object,
value:{}
},
info:{
type:Object,
value:{}
},
isCanDraw: {
type: Boolean,
value: false,
observer(newVal, oldVal) {
newVal && this.drawPic()
}
}
},
data: {
isModal: false, //是否显示拒绝保存图片后的弹窗
imgDraw: {}, //绘制图片的大对象
sharePath: '', //生成的分享图
visible: false
},
methods: {
drawPic() {
let mydate = this.data.actions.filter((ele,index) => {
if(index < 6){
return ele
}
})
console.log(mydate)
wx.getSystemInfo({
success(res) {
console.log(res.model)
}
})
if (this.data.sharePath) { //如果已经绘制过了本地保存有图片不需要重新绘制
this.setData({
visible: true
})
this.triggerEvent('initData')
return
}
wx.showLoading({
title: '生成中'
})
let makeArr = (i,ele) => [
[
{
"type": "rect",
"css": {
"background": "#211F24",
"width": "680px",
"height": "90px",
"top": (388 + 120 * i) + "px",
"left": "34px",
"rotate": "0",
"borderRadius": "8px",
"borderWidth": "2px",
"borderColor": "#736B5E",
"shadow": "",
"color": "#211F24"
}
},
{
"type": "text",
"text": ele.actionName,
"css": {
"color": "#fff",
"background": "rgba(0,0,0,0)",
"width": "230px",
"height": "37.18000000000001px",
"top": (418 + 120 * i) + "px",
"left": "48px",
"rotate": "0",
"borderRadius": "",
"borderWidth": "",
"borderColor": "#000000",
"shadow": "",
"padding": "0px",
"fontSize": "26px",
"fontWeight": "normal",
"maxLines": "1",
"lineHeight": "37.51800000000001px",
"textStyle": "fill",
"textDecoration": "none",
"fontFamily": "",
"textAlign": "left"
}
},
{
"type": "text",
"text": `重量(KG):${ele.weight} 数量(个):${ele.number}`,
"css": {
"color": "#9C8D76",
"background": "rgba(255,255,0,0)",
"width": "420px",
"height": "37.18000000000001px",
"top": (418 + 120 * i) + "px",
"left": "291px",
"rotate": "0",
"borderRadius": "",
"borderWidth": "",
"borderColor": "#000000",
"shadow": "",
"padding": "0px",
"fontSize": "26px",
"fontWeight": "normal",
"maxLines": "1",
"lineHeight": "37.51800000000001px",
"textStyle": "fill",
"textDecoration": "none",
"fontFamily": "",
"textAlign": "left"
}
},
]
]
// arr
let getImage = (url) => {
return new Promise((r,j) => {
wx.getImageInfo({
src: url,
success:(e) => {
console.log(e)
r(e.path)
}
})
})
}
let myavater;
let imgDraw = {
"width": "750px",
"height": "1280px",
"background": "/image/background.jpg",
"views": [
{
"type": "text",
"text": this.data.info.name,
"css": {
"color": "#CC9F5A",
"background": "rgba(0,0,0,0)",
"width": "180px",
"height": "42.89999999999999px",
"top": "174px",
"left": 375 + - (this.data.info.name.length * 15) + "px",
"rotate": "0",
"borderRadius": "",
"borderWidth": "",
"borderColor": "#000000",
"shadow": "",
"padding": "0px",
"fontSize": "30px",
"fontWeight": "normal",
"maxLines": "1",
"lineHeight": "43.290000000000006px",
"textStyle": "fill",
"textDecoration": "none",
"fontFamily": "",
"textAlign": "left"
}
},
{
"type": "image",
"url": wx.getStorageSync('headPortrait'),
"css": {
"width": "131px",
"height": "131px",
"top": "9px",
"left": "318px",
"rotate": "0",
"borderRadius": "134px",
"borderWidth": "3px",
"borderColor": "#CC9F5A",
"shadow": "",
"mode": "scaleToFill"
}
},
{
"type": "image",
"url":'/image/qeur.jpg',
"css": {
"width": "118px",
"height": "118px",
"top": "1110px",
"left": "588px",
"rotate": "0",
"borderRadius": "0",
"borderWidth": "4px",
"borderColor": "#CC9F5A",
"shadow": "",
"mode": "scaleToFill"
}
},
{
"type": "text",
"text": "今天训练容量 (KG):" + this.data.info.rongliang,
"css": {
"color": "#fff",
"background": "rgba(0,0,0,0)",
"width": "720px",
"height": "42.89999999999999px",
"top": "326px",
"left": "30px",
"rotate": "0",
"borderRadius": "",
"borderWidth": "",
"borderColor": "#000000",
"shadow": "",
"padding": "0px",
"fontSize": "30px",
"fontWeight": "normal",
"maxLines": "2",
"lineHeight": "43.290000000000006px",
"textStyle": "fill",
"textDecoration": "none",
"fontFamily": "",
"textAlign": "left"
}
},
{
"type": "text",
"text": "在****已经坚持"+ this.data.info.count +"天",
"css": {
"color": "#CC9F5A",
"background": "rgba(0,0,0,0)",
"width": "340px",
"height": "42.89999999999999px",
"top": "231px",
"left": "210px",
"rotate": "0",
"borderRadius": "",
"borderWidth": "",
"borderColor": "#000000",
"shadow": "",
"padding": "0px",
"fontSize": "30px",
"fontWeight": "normal",
"maxLines": "2",
"lineHeight": "43.290000000000006px",
"textStyle": "fill",
"textDecoration": "none",
"fontFamily": "",
"textAlign": "center"
}
},
]
}
console.log(imgDraw.views)
mydate.forEach((ele,i) => {
makeArr(i,ele).forEach(ele => {
imgDraw.views.push(...ele)
})
})
this.setData({
imgDraw:imgDraw
})
},
onImgErr(e) {
wx.hideLoading()
wx.showToast({
title: '生成分享图失败,请刷新页面重试'
})
},
onImgOK(e) {
wx.hideLoading()
this.setData({
sharePath: e.detail.path,
visible: true,
})
//通知外部绘制完成,重置isCanDraw为false
this.triggerEvent('initData')
},
preventDefault() { },
// 保存图片
savePhoto(path) {
wx.showLoading({
title: '正在保存...',
mask: true
})
this.setData({
isDrawImage: false
})
wx.saveImageToPhotosAlbum({
filePath: path,
success: (res) => {
wx.showToast({
title: '保存成功',
icon: 'none'
})
setTimeout(() => {
this.setData({
visible: false
})
}, 300)
},
fail: (res) => {
wx.getSetting({
success: res => {
let authSetting = res.authSetting
if (!authSetting['scope.writePhotosAlbum']) {
this.setData({
isModal: true
})
}
}
})
setTimeout(() => {
wx.hideLoading()
this.setData({
visible: false
})
}, 300)
}
})
}
}
})
目前微信小程序已经可以直接分享到朋友圈了
可以参考我这个文章