1.直接使用
html部分
<view ="doposter">下载海报</view>
<canvas canvas-id="myCanvas" type='2d' style="width: 370px; height: 550px;opcity:0;position: fixed;z-index:-1;" id="myCanvas" />
js 部分
drawBackground() {
const canvasId = 'myCanvas'
const ctx = uni.createCanvasContext(canvasId, this)
const title = this.title
const goodsCover = this.selcetShareImgUrl // 分享商品图片 需要换成自己的产品图片
const goodsTitle = this.goods.name // 商品名称
const goodsPrice = '¥ '+this.goods.original_price
const des1 = '① 长按识别二维码'
const des2 = '② 查看商品详情'
const qrcode = this.goods.share.code //二维码地址 需要换成自己的二维码
// 绘制背景图
ctx.setFillStyle('#fff')
ctx.fillRect(0, 0, 370, 550)
// 字体颜色
ctx.setFontSize(17)
ctx.setFillStyle('#111')
ctx.fillText(title, 50, 39.9)
ctx.fillText(title, 49.9, 40)
ctx.fillText(title, 50,40)
ctx.fillText(title, 50, 40.1)
ctx.fillText(title, 50.1, 40.1)
// 商品名称 且拦截页面文字长度
let titleGoods = this.goods.name.split('').length <= 20 ? this.goods.name : this.goods.name.substring(0,18)+' ...'
ctx.setFontSize(16)
ctx.setFillStyle('#111')
ctx.fillText(titleGoods , 30 , 420)
// 商品价格
ctx.setFontSize(18)
ctx.setFillStyle('#f36d00')
ctx.fillText(goodsPrice, 29.9, 450)
ctx.fillText(goodsPrice, 30,450)
ctx.fillText(goodsPrice, 30, 450.1)
ctx.fillText(goodsPrice, 30.1, 450)
// 二维码描述
ctx.setFontSize(13)
ctx.setFillStyle('#999')
ctx.fillText(des1, 30, 490)
ctx.setFontSize(13)
ctx.setFillStyle('#999')
ctx.fillText(des2, 30, 520)
uni.downloadFile({
url:goodsCover,
success: (res) => {
// 商品图片
ctx.drawImage(res.tempFilePath, 30, 70, 310, 310)
// 二维码
ctx.drawImage(qrcode, 240, 420, 110, 110)
ctx.draw(false, () => {
uni.canvasToTempFilePath({
canvasId: canvasId,
success: (res) => {
console.log('临时图片路径:', res.tempFilePath);
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
uni.hideLoading()
uni.showModal({
title: '提示',
content: ' 图片保存成功',
showCancel: false,
confirmText: '知道了',
confirmColor: '#f36d00',
success: res => {
uni.navigateBack()
}
})
}
})
},
fail: (error) => {
console.error('转化图片失败:', error);
}
},this)
});
}
})
},
async doposter() {
uni.showLoading({
title: '正在生成海报'
});
await this.drawBackground();
},
2.拆分成组件方便使用组件
<template>
<view>
<canvas canvas-id="myCanvas" type='2d' style="width: 370px; height: 550px; opacity:0;position: fixed;z-index:-1;" id="myCanvas" />
</view>
</template>
<script>
export default {
name:"shareQrcode",
data() {
return {
canvasId:'myCanvas',
canvasImgPath :''
};
},
props:{
shareInfo:{
type:Object,
default:() => {
return{
bgColor : '#fff',
title : '看到这个第一眼就想分享给你',
goodsCover : 'http://storage.zh.shangkelian.cn/images/2022/01/07/08e732962fc55a2a196f193c94c22cf9.png', // 换自己图片
goodsTitle : '大菠萝大菠萝大菠萝蜜菠萝蜜大菠萝大菠萝大菠萝蜜菠萝蜜', // 商品名称
goodsPrice : '¥ 123',
des1 : '① 长按识别二维码',
des2 : '② 查看商品详情',
qrcode : require('@/static/ewm.png'), //二维码地址
}
}
}
},
methods:{
drawBackground() {
const canvasId = this.canvasId
const ctx = uni.createCanvasContext(canvasId, this)
const bgColor = this.shareInfo.bgColor
const title = this.shareInfo.title
const goodsCover = this.shareInfo.goodsCover
const goodsTitle = this.shareInfo.goodsTitle
const goodsPrice = this.shareInfo.goodsPrice
const des1 = this.shareInfo.des1
const des2 = this.shareInfo.des2
const qrcode = this.shareInfo.qrcode
// 绘制背景图
ctx.setFillStyle(bgColor)
ctx.fillRect(0, 0, 370, 550)
// 字体颜色
ctx.setFontSize(17)
ctx.setFillStyle('#111')
ctx.fillText(title, 50, 39.9)
ctx.fillText(title, 49.9, 40)
ctx.fillText(title, 50,40)
ctx.fillText(title, 50, 40.1)
ctx.fillText(title, 50.1, 40.1)
// 商品名称
let titleGoods = goodsTitle.split('').length <= 20 ? goodsTitle : goodsTitle.substring(0,18)+' ...'
ctx.setFontSize(16)
ctx.setFillStyle('#111')
ctx.fillText(titleGoods , 30 , 420)
// 商品价格
ctx.setFontSize(18)
ctx.setFillStyle('#f36d00')
ctx.fillText(goodsPrice, 29.9, 450)
ctx.fillText(goodsPrice, 30,450)
ctx.fillText(goodsPrice, 30, 450.1)
ctx.fillText(goodsPrice, 30.1, 450)
// 二维码描述
ctx.setFontSize(13)
ctx.setFillStyle('#999')
ctx.fillText(des1, 30, 490)
ctx.setFontSize(13)
ctx.setFillStyle('#999')
ctx.fillText(des2, 30, 520)
uni.downloadFile({
url:goodsCover,
success: (res) => {
// 商品图片
ctx.drawImage(res.tempFilePath, 30, 70, 310, 310)
// 二维码
ctx.drawImage(qrcode, 250, 440, 90, 90)
// #ifdef MP-WEIXIN
console.log('...........downloadFile............')
wx.showModal({
title:'作者友情提示',
content:'小程序端生成二维码功能暂未完善,作者会尽快完成的!',
showCancel:false,
confirmText:'我已知道',
confirmColor:'green'
})
uni.hideLoading()
// 保存海报
// uni.canvasToTempFilePath({
// canvasId: canvasId,
// success: (res) => {
// console.log(res)
// this.canvasImgPath = res.tempFilePath
// // this.save()
// },
// fail: (error) => {
// console.error('转化图片失败:', error)
// }
// },this)
return
// #endif
// app 和 h5 调用这个方法
ctx.draw(false, () => {
uni.canvasToTempFilePath({
canvasId: canvasId,
success: (res) => {
this.canvasImgPath = res.tempFilePath
this.save()
},
fail: (error) => {
console.error('转化图片失败:', error)
}
},this)
})
}
})
},
// 生成本地海报
async doposter() {
uni.showLoading({
title: '正在生成海报'
});
await this.drawBackground()
},
// 获取权限( 只适用于小程序)
saveAlbum(){
wx.hideLoading()
//获取权限保存相册
uni.getSetting({//获取用户的当前设置
success:(res)=> {
console.log(res.authSetting['scope.writePhotosAlbum'])
if(res.authSetting['scope.writePhotosAlbum']){//验证用户是否授权可以访问相册
this.save();
}else{
uni.authorize({//如果没有授权,向用户发起请求
scope: 'scope.writePhotosAlbum',
success:()=> {
this.save();
},
fail:()=>{
uni.showToast({
title:"请打开保存相册权限,再点击保存相册分享",
icon:"none",
duration:3000
});
setTimeout(()=>{
uni.openSetting({//调起客户端小程序设置界面,让用户开启访问相册
success:(res2)=> {
// console.log(res2.authSetting)
}
});
},3000);
}
})
}
},
fail: (error) => {
console.log(error)
}
})
},
// 保存海报
save(){
// #ifdef APP
uni.saveImageToPhotosAlbum({
filePath: this.canvasImgPath,
success: () => {
uni.hideLoading()
uni.showModal({
title: '提示',
content: ' 图片保存成功',
showCancel: false,
confirmText: '知道了',
confirmColor: '#f36d00',
success: res => {
uni.navigateBack()
}
})
}
})
// #endif
// #ifdef H5
uni.hideLoading()
var oA = document.createElement("a");
oA.download = ''; // 设置下载的文件名,默认是'下载'
oA.href = this.canvasImgPath;
document.body.appendChild(oA);
oA.click();
oA.remove(); // 下载之后把创建的元素删除
// #endif
// #ifdef MP-WEIXIN
console.log('wx',this.canvasImgPath)
// uni.saveImageToPhotosAlbum({
// filePath: this.canvasImgPath,
// success: () => {
// uni.hideLoading()
// uni.showModal({
// title: '提示',
// content: ' 图片保存成功',
// showCancel: false,
// confirmText: '知道了',
// confirmColor: '#f36d00',
// success: res => {
// uni.navigateBack()
// }
// })
// }
// })
// #endif
}
}
}
</script>
<style>
</style>
父组件中引用
<template>
<view>
<shareQrcode ref="shareQrcode" :shareInfo="shareInfo"/>
<button type="primary" ="$refs.shareQrcode.doposter()">二维码生成图片</button>
</view>
</template>
<script>
import shareQrcode from '@/components/share-qrcode.vue'
export default {
data() {
return {
shareInfo:{
// 背景色
bgColor : '#fff',
// 标题
title : '看到他的第一时间就忍不住分享给你',
// 商品图
goodsCover : 'http://storage.zh.shangkelian.cn/images/2022/01/07/08e732962fc55a2a196f193c94c22cf9.png',
// 商品名称
goodsTitle : '大菠萝大菠萝大菠萝蜜菠萝蜜大菠萝大菠萝大菠萝蜜菠萝蜜',
// 商品价格
goodsPrice : '¥ 123',
// 二维码描述
des1 : '① 长按识别二维码',
// 二维码描述
des2 : '② 查看商品详情',
//二维码地址
qrcode : require('@/static/ewm.png'),
}
}
},
components:{
shareQrcode
},
}
</script>
<style>
</style>