通过微信小程序的canvas生成分享海报 放置海报的 canvas
<canvas
v-show="false"
class="canvas"
type="2d"
id="myCanvas"
style="width: 622rpx; height: 858rpx"
></canvas>
data内容
data () {
return {
show: false, //控制显示海报的弹窗的变量
imageShow: false, //控制海报显示的变量
url: '', //海报路径
qr_code: '', //二维码路径
}
},
点击生成海报函数
developers.weixin.qq.com/miniprogram…
handleSharp() {
//这是控制显示海报的弹窗控件
this.show = true
uni.showLoading({
title: '生成分享海报中...',
})
//this 重新赋值 因为下面的函数中this指针会改变
const that = this
//获取canvas的dome节点
const query = uni.createSelectorQuery().in(this)
query
.select('#myCanvas')
.fields({
node: true,
size: true,
})
.exec((res) => {
//#region 获取节点,设置像素
const canvas = res[0].node
const ctx = canvas.getContext('2d')
// 绘制前,先清空上一次的绘制
ctx.clearRect(0, 0, canvas.width, canvas.height)
//获取设备像素比
const dpr = wx.getSystemInfoSync().pixelRatio
canvas.width = 622 * dpr
canvas.height = (858 - 64) * dpr
ctx.scale(dpr, dpr)
//#endregion
//绘制网络图片时,要先下载 ,通过 uni.downloadFile下载
uni
.downloadFile({
url: 'https://img2.baidu.com/it/u=1441022992,3594689583&fm=253&fmt=auto&app=120&f=JPEG?w=1422&h=800',
})
.then(async (res) => {
获取二维码的图片路径
await that.handleQrcode()
//#region 创建图片对象
const img = canvas.createImage()
img.src = res[1].tempFilePath
//#endregion
img.onload = () => {
//图片加载完通过drawImage绘制上去
ctx.drawImage(img, 0, 0, 622, 318)
//绘制放置海报内容盒子的函数
that.handleCanvas(0, 264, 622, 562, 32, ctx)
//绘制放置海报内容的函数
that.handleCanvasText(ctx, '这是内容', 40, 336, 36, '#000000')
//绘制放置二维码的图片对象
const img_qrcode = canvas.createImage()
img_qrcode.src = that.qr_code
img_qrcode.onload = function () {
ctx.drawImage(img_qrcode, 40, 600, 120, 120)
//生成临时路径的api 方便通过image在页面显示和下载
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: 622,
height: 858 - 64,
destWidth: 622 * dpr,
destHeight: 858 * dpr,
canvasId: 'myCanvas',
canvas: canvas,
success(res) {
console.log('海报临时路径为:', res.tempFilePath)
that.url = res.tempFilePath
that.imageShow = true
//关闭loading
uni.hideLoading()
},
fail(res) {
console.error(res)
},
})
}
}
})
// await that.handleQrcode()
// ctx.drawImage(img, 0, 0, 622, 318)
// }
})
},
二维码canvas 通过插件生成二维码 npm i weapp-qrcode-canvas-2d
<canvas
v-show="false"
type="2d"
style="width: 120rpx; height: 120rpx"
id="myQrcode"
></canvas>
获取二维码的函数
//引入插件
import drawQrcode from 'weapp-qrcode-canvas-2d'
handleQrcode() {
return new Promise((resolve, reject) => {
const that = this
const query = uni.createSelectorQuery().in(this)
query
.select('#myQrcode')
.fields({
node: true,
size: true,
})
.exec((res) => {
const canvas = res[0].node
const ctx = canvas.getContext('2d')
ctx.clearRect(0, 0, canvas.width, canvas.height)
uni
.downloadFile({
url: 'https://hr-zhoushuren-1312551878.cos.ap-guangzhou.myqcloud.com/0203r1200092xxh1mA5E2_W_1080_808_R5_D.png',
})
.then((res) => {
const img = canvas.createImage()
img.src = res[1].tempFilePath
//#endregion
img.onload = () => {
var options = {
canvas: canvas,
canvasId: 'myQrcode',
width: 260,
padding: 30,
paddingColor: '#fff',
background: '#fff',
foreground: '#000000',
text: '内容',
image: {
imageResource: img,
width: 80, // 建议不要设置过大,以免影响扫码
height: 80, // 建议不要设置过大,以免影响扫码
round: true, // Logo图片是否为圆形
},
}
drawQrcode(options)
// 获取临时路径
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: 260,
height: 260,
destWidth: 600,
destHeight: 600,
canvasId: 'myQrcode',
canvas: canvas,
success(res) {
console.log('二维码临时路径为:', res.tempFilePath)
that.qr_code = res.tempFilePath
resolve()
},
fail(res) {
reject(res)
},
})
}
})
})
})
},
海报内容盒子的函数
//传递参数分别为 x坐标,y坐标,宽度,高度,半径,canvas上下文(即canvas节点)
handleCanvas(x, y, w, h, r, ctx) {
// 设置填充色
ctx.fillStyle = '#fff'
// 绘制圆角矩形
ctx.moveTo(x + r, y)
ctx.lineTo(x + w - r, y)
ctx.arc(x + w - r, y + r, r, -Math.PI / 2, 0)
ctx.lineTo(x + w, y + h - r)
// ctx.arc(x + w - r, y + h - r, r, 0, Math.PI / 2)
ctx.lineTo(x, y + h - r)
// ctx.arc(x + r, y + h - r, r, Math.PI / 2, Math.PI)
// ctx.lineTo(x, y + r)
ctx.arc(x + r, y + r, r, Math.PI, (Math.PI * 3) / 2)
// 填充圆角矩形
ctx.fill()
},
海报文字内容函数
//传递参数分别为 canvas上下文(即canvas节点),文字内容,x坐标,y坐标,字体大小,颜色
handleCanvasText(ctx, text, x, y, size, color) {
let newText = text
let chr = newText.split('')
let temp = ''
let row = []
ctx.font = `${size}px Arial`
ctx.fillStyle = color
for (var a = 0; a < chr.length; a++) {
if (ctx.measureText(temp).width < 542) {
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], x, y + b * (size + 10))
}
},
},
展示效果
以上微信api如果不起作用,大概率是微信api淘汰了,请去微信官方文档查阅 developers.weixin.qq.com/miniprogram…
如有错漏,请指出评论
受教了