需求:小程序中webview页面H5可以分享至朋友圈
解决:生成带小程序码的海报,在H5页面长按保存海报图片,自行分享至朋友圈。
海报如下:
绘制海报主要是三个部分
1. 贴图
需要注意的是,有时候图片未加载成功,导致未贴上图,所以需要在onload 事件中绘制图。
var c=document.getElementById("canvas");
var ctx=c.getContext("2d");
var img=document.getElementById("tulip");
img.onload = ()=>{
ctx.drawImage(img,20,20);
}
2. 绘文字
写文字,需要注意换行问题。
一行文字的高度,宽度,基线是需要注要的地方。
基线和行高不注意的话,可能导致绘制出来的图和UI 对不上。
我们可以写一个公共函数
/**
context
t 文字
x,y 坐标
lineHeight 文字一行高度
maxLineNum 文字显示的行数
Linewidth 一行文字的宽度
*/
drawText(context, t, x, y, Linewidth, lineHeight, maxLineNum){
let LineHeight = lineHeight || 24 // 默认行高24px
let maxlineNum = maxLineNum || 2 // 文字行数默认2行
var chr = t.split("");
var temp = "";
var row = []; // 行数
// 分行
for(var a = 0; a < chr.length; a++){
//context.measureText(text).width 测量文本text的宽度
if(context.measureText(temp).width < Linewidth && context.measureText(temp+(chr[a])).width <= Linewidth){
temp += chr[a];
}else{
row.push(temp);
temp = chr[a];
}
}
row.push(temp);
// 在canvas 中绘制
for(var b = 0; b < row.length; b++){
if (b < maxlineNum-1){
context.fillText(row[b],x,y+(b)*LineHeight);
} else if( (b == maxlineNum-1)){
context.fillText(row[b] + '...', x, y+(b)*LineHeight);
}
}
}
举例:
var c=document.getElementById("canvas");
var ctx=c.getContext("2d");
let t = "888888888向克罗地亚新任总统米拉诺维奇致贺88888向克罗地亚新任总统米拉诺维奇致贺电";
ctx.font = "bold 18px arial";
ctx.fillStyle = "black";
ctx.textBaseline = "top"; // 基线比较重要
this.drawText(ctx, t, 20, 210, 295, 25, 2)
3.画横线
虚线
// 绘制线条
ctx.beginPath();
ctx.lineWidth="1";
ctx.setLineDash([3,3]);
ctx.strokeStyle="#E9E8EB";
ctx.moveTo(0, 280);
ctx.lineTo(335,280);
ctx.stroke(); // 进行绘制
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="canvas" width="335" height="371"></canvas>
<img src="pic.png" id="tulip"></img>
<img src="miniPro.jpg" id="code"></img>
<img src="userImage.jpg" id="userImage"></img>
</body>
<script>
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
// 背景图
ctx.fillStyle = "#ffffff";
ctx.fillRect(0, 0, 335, 371);
var img = document.getElementById("tulip");
img.onload = function () {
ctx.drawImage(img, 20, 20);
}
// 新闻标题
let t = "45654向克罗地亚新任123米拉诺维奇致贺电123向克罗地亚新任123米拉诺维奇致贺电";
ctx.font = "bold 18px arial";
ctx.fillStyle = "black";
ctx.textBaseline = "top";
drawText(ctx, t, 20, 210, 295, 25, 2)
// 绘制线条
ctx.beginPath();
ctx.lineWidth = "1";
ctx.setLineDash([3, 3]);
ctx.strokeStyle = "#E9E8EB"; // 红色路径
ctx.moveTo(0, 280);
ctx.lineTo(335, 280);
ctx.stroke(); // 进行绘制
// 二维码 (20, 301)
var img1 = document.getElementById("code");
img1.onload = function () {
ctx.drawImage(img1, 10, 290, 70, 70);
}
// 用户信息
// 用户头像,坐标(85, 371-20-48)
var userImage = document.getElementById("userImage");
userImage.onload = function () {
ctx.drawImage(userImage, 85, 303, 20, 20);
}
// 用户名,坐标(110, 371-49-18),行高18
var userName = "吃*******"
ctx.font = "bold 13px arial";
ctx.fillStyle = "black";
ctx.textBaseline = "top";
drawText(ctx, userName, 110, 303, 100, 18)
// 坐标(159, 371-49-18)
var readTip = "正在阅读这篇文章"
ctx.font = "normal 13px arial";
ctx.fillStyle = "black";
ctx.textBaseline = "top";
drawText(ctx, readTip, 199, 303, 150, 18)
// 推荐文字
let word = "长按小程序码,进入 **小程序 阅读全文"
ctx.font = "12px arial";
ctx.fillStyle = "black";
ctx.textBaseline = "top";
drawText(ctx, word, 85, 331, 224, 17)
/**
lineHeight 文字行高
maxLineNum 文字行数
Linewidth 行的宽度
*/
function drawText(context, t, x, y, Linewidth, lineHeight, maxLineNum) {
let LineHeight = lineHeight || 24
let maxlineNum = maxLineNum || 2
var chr = t.split("");
var temp = "";
var row = [];
for (var a = 0; a < chr.length; a++) {
//context.measureText(text).width 测量文本text的宽度
if (context.measureText(temp).width < Linewidth && context.measureText(temp + (chr[a])).width <= Linewidth) {
temp += chr[a];
} else {
row.push(temp);
temp = chr[a];
}
}
row.push(temp);
for (var b = 0; b < row.length; b++) {
if (b < maxlineNum - 1) {
context.fillText(row[b], x, y + (b) * LineHeight);
} else if ((b == maxlineNum - 1)) {
context.fillText(row[b] + '...', x, y + (b) * LineHeight);
}
}
}
</script>
</html>