canva实现微信小程序商品分享海报
前言
使用canvas画布实现小程序分享海报功能
一、定义一个生成海报按钮
1.点击按钮生成海报
catchtap:handleShare 使用catch绑定阻止事件冒泡
<view class="poster_window " catchtap="handleShare">
<view class="poster_warp">
<image src="/icons/posticon.png" mode="widthFix" lazy-load="true"></image>
<view class="post_text">生成海报</view>
</view>
</view>
二、定义一个生成海报的方法
1.调用wx.createSelectorQuery()获取页面节点信息以及使用canvas.getContext创建画布
代码如下(示例):
/* 生成海报方法 */
data:{
startDateTime:'', //开团时间
endDateTime:'',//截团时间
dateTime:'',//当前时间
showShare:true,//显示分享海报
newsImg:'',// 海报商品图
postimg:'',
goodsUrl:'',
newText:'',
canvas:'',
ctx:'',
dpr:'',
Img:'',
codeImg:''
},
onLoad: function () {
this.creatImage()
},
creatImage(){
const query = wx.createSelectorQuery()
query.select('#myCanvas')
.fields({ node: true, size: true })
.exec((res) => {
const canvas = res[0].node
const ctx = canvas.getContext('2d')
const dpr = wx.getSystemInfoSync().pixelRatio
canvas.width = res[0].width * dpr
canvas.height = res[0].height * dpr
ctx.scale(dpr, dpr)
ctx.fillStyle = '#ffffff'//背景颜色
ctx.fillRect(0, 0, 300, 485)
this.setData({
canvas,
ctx,
dpr
})
this.drawHeader()
this.goodsImg()
this.price()
this.goodsname()
this.codeImg()
})
},
2.海报顶部图片
代码如下(示例):
/* 顶部图片 */
drawHeader(){
let {canvas,ctx} = this.data
const headImg = canvas.createImage()
headImg.src = '/images/pbg.png'
headImg.onload = () =>{
ctx.drawImage(headImg, 0, 0, 300, 50)
}
},
3.海报商品图片
代码如下(示例):
/* 商品图片 */
goodsImg(){
let {canvas,ctx,endDateTime} = this.data
let oldTime = new Date(endDateTime)
var month = (oldTime.getMonth()+1)<10?'0'+(oldTime.getMonth()+1):(oldTime.getMonth()+1)
var date = (oldTime.getDate())<10?'0'+(oldTime.getDate()):(oldTime.getDate())
var hours = (oldTime.getHours())<10?'0'+(oldTime.getHours()):(oldTime.getHours())
var minutes = (oldTime.getMinutes())<10?'0'+(oldTime.getMinutes()):(oldTime.getMinutes())
var DateTime = month+ '月'+date+ '日' + ' '+hours+':'+minutes
const goodsImg = canvas.createImage()
goodsImg.src = this.data.goodsUrl
goodsImg.onload = () =>{
ctx.drawImage(goodsImg,10,60,280,280)
var grd=ctx.createLinearGradient(0,0,170,0);
grd.addColorStop(0,"#F53C28");
grd.addColorStop(1,"#79235E");
ctx.fillStyle = grd;
ctx.fillRect(10,310,220,30);
ctx.fillStyle = '#ffffff';
ctx.font="14px Arial";
ctx.fillText("限时抢购",15,330);
ctx.fillStyle = '#ffffff';
ctx.font="14px Arial";
ctx.fillText(DateTime+"截团",90,330);
ctx.beginPath()
ctx.moveTo(80,320);
ctx.lineTo(80,332);
ctx.lineWidth=1.5;
ctx.strokeStyle="#ffffff";
ctx.stroke()
}
},
4.商品价格
代码如下(示例):
/* 价格 */
price(){
let {ctx} = this.data
ctx.fillStyle = "#F53C28";
ctx.font="18px Arial";
ctx.fillText("¥",10,375);
ctx.font="22px Arial";
ctx.fillText(this.data.minPrice(商品价格)+' 起',30,375);
},
5.商品名称
代码如下(示例):
goodsname(){
let {ctx,newText} = this.data
let chr = newText.split("");
let temp = "";
let row = [];
ctx.font="16px Arial";
ctx.fillStyle = "#000000";
for (var a = 0; a < chr.length; a++) {
if (ctx.measureText(temp).width < 155) {
temp += chr[a];
}
else {
a--; //这里添加了a-- 是为了防止字符丢失,效果图中有对比
row.push(temp);
temp = "";
}
}
row.push(temp);
if (row.length > 3) {
var rowCut = row.slice(0, 3);
var rowPart = rowCut[2];
var test = "";
var empty = [];
for (var a = 0; a < rowPart.length; a++) {
if (ctx.measureText(test).width < 220) {
test += rowPart[a];
}
else {
break;
}
}
empty.push(test);
var group = empty[0] + "..."//这里只显示两行,超出的用...表示
rowCut.splice(2, 1, group);
row = rowCut;
}
for (var b = 0; b < row.length; b++) {
ctx.fillText(row[b], 10, 405 + b * 25, 300);
}
},
6.小程序二维码
代码如下(示例):
codeImg(){
let {canvas,ctx} = this.data
const codeImg = canvas.createImage()
codeImg.src = this.data.codeImg//小程序二维码图片
codeImg.onload = () =>{
ctx.save()
ctx.drawImage(codeImg, 200, 355, 85,85)
ctx.restore()
ctx.fillStyle = '#000000';
ctx.font="12px Arial";
ctx.fillText("长按扫码下单",207,460);
}
},
7.点击生成海报
代码如下(示例):
/* 显示海报 */
async handleShare(e){
await showToast({
title:'海报生成中...',
icon:'loading'
})
setTimeout(() => {
this.createImg()
this.setData({
showShare:false
})
}, 2000);
},
/* 生成图片 */
createImg(){
wx.canvasToTempFilePath({
canvas: this.data.canvas,
width: 300,
height: 485,
success:res=> {
this.setData({
postimg:res.tempFilePath
})
}
})
},
总结
这只是一个制作生成分享海报的一个方法,具体海报的布局根据需求完成!