小程序canvas生成海报
发表时间:2020-9-29
发布人:葵宇科技
浏览次数:92
小程序canvas生成海报
- 先看看效果图 以下↓
- 使用场景
- 前提
- wxml
- js
- drawCanvas.js
- 在Canvas.js引入drawCanvas.js
- 希望大家能够用到!
如果文章中有出现纰漏、错误之处,还请看到的小伙伴多多指教,先行谢过
先看看效果图 以下↓
使用场景
- 分享小程序的,绘制分享图
- 不同商品分享的是后生成不同的图片,每个商品的信息图片不同,小程序默认分享的是页面默认截图
- 小程序分享朋友圈,生成海报
前提
- 根据上面图片需要一个背景图片(上面是750*777),大家可根据实际情况进行改变
- 本文用的是小程序canvas最新api,大家可以阅读小程序canvas文档
wxml
<canvas style="width:750px;height:777px;position:absolute;top:0px;left:-2000px;" id="canvas" type="2d"></canvas>
js
drawCanvas.js
[单独创建drawCanvas.js存放一些公共函数,里面封装了图片渲染文字换行等一些方法(由于画布无法直接使用网络图片,所以需要 wx.downloadFile或者wx.getImageInfo把它下载回来才能使用,本文使用wx.downloadFile)]
export default {
// 下载图片函数
downloadImg(img) {
return new Promise((resolve, reject) => {
//将网络图片转成本地路径
// wx.getImageInfo({
// src: img,
// success: function (res) {
// resolve(res.path)
// }
// })
//方法二
wx.downloadFile({
url: img,
success: (res) => {
let cover = res.tempFilePath;
resolve(cover)
},
fail: (err) => {
reject(err)
},
})
})
},
//图片渲染
drawImage(canvas, ctx, imgUrl, x, y, w, h) {
ctx.save();
const img = canvas.createImage();
img.src = imgUrl
img.onload = () => ctx.drawImage(img, x, y, w, h);
ctx.closePath();
},
//文字换行
drawTxt: function (ctx, _str, _x, _y, _total, _lineh, _linenum) {
if (_str == "" || _str == undefined) {
return;
}
var total = _total ? _total : 15; //每行字数(数字算半个)
var lineH = _lineh ? _lineh : 20; //行间距
var lineNum = _linenum ? _linenum : 4; //最大显示行数
/*
拆解字符串到数组,按行,每行15个(判断数字占半个,其他占1个)
*/
var lineArray = [];
var len = 0; //数字算半个,中文算一个
for (var i = 0; i < _str.length; i++) {
var line = '';
if (Math.ceil(len) % total == 0) {
if (lineArray[lineArray.length - 1] != "") {
lineArray.push("");
}
}
var index = Math.floor(len / total); //
lineArray[index] = lineArray[index] + _str[i];
if (!isNaN(_str[i])) {
//是数字
len = len + 0.5;
} else {
len = len + 1;
}
}
for (var i = 0; i < lineArray.length; i++) {
var t_str = lineArray[i];
if (lineArray.length > lineNum && i == (lineNum - 1)) {
//如果总行数大于设定的行数,则到最大设定行时,加省略号,退出
t_str = t_str + '...'
ctx.fillText(t_str, _x, _y + lineH * i);
break;
} else {
ctx.fillText(t_str, _x, _y + lineH * i);
}
}
},
//裁切圆角
drawRoundRect: function (cxt, x, y, width, height, radius) {
cxt.save()
cxt.beginPath();
cxt.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2);
cxt.lineTo(width - radius + x, y);
cxt.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2);
cxt.lineTo(width + x, height + y - radius);
cxt.arc(width - radius + x, height - radius + y, radius, 0, Math.PI * 1 / 2);
cxt.lineTo(radius + x, height + y);
cxt.arc(radius + x, height - radius + y, radius, Math.PI * 1 / 2, Math.PI);
cxt.closePath();
}
}
在Canvas.js引入drawCanvas.js
import drawCanvas from 'drawCanvas.js';
Page(Object.assign({},drawCanvas, {
/**
* 页面的初始数据
*/
data: {
canvasImg: 'https://dss0.baidu.com/6ONWsjip0QIZ8tyhnq/it/u=2635355882,2630309952&fm=218&app=2&f=JPEG?w=121&h=75&s=FF7204C5C0615D0773AD7CD103003098' // 实例
},
/**
* 生命周期函数--监听页面加载
*/
>: function (options) {
this.shareCreate()
},
//分享微信朋友圈
async shareCreate() {
var self = this;
//self.downloadImg是drawCanvas.js里面方法
let imgUrl = await self.downloadImg(self.data.canvasImg);
wx.nextTick(() => { self.drawAll(imgUrl) })
},
drawAll(imgUrl) {
const query = wx.createSelectorQuery()
const node = query.select('#canvas').node();
var self = this;
node.exec(async res => {
const canvas = res[0].node;
//设置宽高
canvas.width = canvas._width
canvas.height = canvas._height
const ctx = canvas.getContext('2d');
//背景图
await self.drawImage(canvas, ctx, "/images/shareImg.png", 0, 0, 750, 777);
//cover
await self.drawImage(canvas, ctx, imgUrl, 0, 0, 750, 460);
//logo
await self.drawImage(canvas, ctx, imgUrl, 50, 525, 363, 45);
setTimeout(async () => {
//背景透明
ctx.fillStyle = 'rgba(0, 0, 0, 0.6)';
ctx.fillRect(0, 0, 750, 460);
//绘制空心矩形
ctx.strokeStyle = 'rgba(0, 0, 0, 0.6)';
ctx.strokeRect(0, 0, 750, 460);
ctx.save();
//title
ctx.textAlign = 'left';
ctx.fillStyle = 'rgba(255, 255, 255, 1)';
ctx.font = "normal bold 41px PingFangSC-Regular";
self.drawTxt(ctx, "测试卡片", 50, 390, 30, 50, 1);
//desc
ctx.textAlign = 'left';
ctx.fillStyle = "#1e1e1e";
ctx.font = "normal normal 28px PingFangSC-Regular";
self.drawTxt(ctx, "测试卡片测试卡片测试卡测试卡片片测试卡片测试卡片测试卡片测试卡片测试卡片测试卡片片测试卡片测试卡片", 159, 661, 18, 43, 2);
//裁切圆角
self.drawRoundRect(ctx, 50, 625, 92, 92, 46);
ctx.clip();
ctx.stroke();
//头像
await self.drawImage(canvas, ctx, imgUrl, 50, 625, 92, 92);
ctx.restore();
ctx.closePath();
//canvas转成图片
self.previewHB(canvas)
}, 500)
})
},
//图片预览
previewHB(canvas) {
var self = this;
wx.nextTick(() => {
//转换图片
wx.canvasToTempFilePath({
canvas: canvas,
success:async (res)=> {
let img=res.tempFilePath
//预览
wx.previewImage({
urls: [img]
})
}
})
})
},
}})