最近在做一个项目,是在网页上生成系列海报,海报中有用户头像、图片、文字等信息,也就是比较常见的分享海报,这里做个简单的实现和记录。
用到的js:
<script src="https://cdn.bootcdn.net/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
html部分:
<div>
<img id="imageBox" src="" alt="" />
<button id="previous">上一张</button>
<button id="next">下一张</button>
<span id="tips">当前图片:第(1)张</span>
<div id="qrcodeBox"></div>
<div id="loading">loading......</div>
</div>
script部分:
<script>
let posterData = {
'img': 'https://xxx/img.jpg',
'name': '皮卡乒皮卡乓',
'share_id': 1,
'list': [
{
id: 1,
poster: 'https://xxx/poster1.jpg'
},
{
id: 2,
poster: 'https://xxx/poster2.jpg'
}
]
}
i = 0;
$('#next').click(function () {
if (i < posterData.list.length - 1) {
$('#loading').css('display','block');
i++;
generatePoster(i);
$('#tips').text('当前图片:第(' + (i + 1) + ')张')
} else {
alert('没有更多了+')
}
});
$('#previous').click(function () {
if (i > 0) {
$('#loading').css('display','block');
i--;
generatePoster(i);
$('#tips').text('当前图片:第(' + (i + 1) + ')张')
} else {
alert('没有更多了-')
}
});
// 默认显示第一个
generatePoster(i);
function generatePoster(i) {
let activeData = posterData.list[i];
let qrcodeId = '#qrcode' + activeData.id;
// 对应的二维码不存在才生成
if (typeof($(qrcodeId)[0]) == "undefined") {
// 先生成二维码,防止二维码生成过慢,合成没显示
$('#qrcodeBox').append('<div id="qrcode' + activeData.id + '" style="display: none;"></div>')
new QRCode($(qrcodeId)[0], {
text: "https://xxxxxx.html?active_id=" + activeData.id + '&share_id=' + posterData.share_id,
width: 90,
height: 90,
correctLevel: 0 // 二维码结构复杂性 0~3
});
}
let canvasWidth = 424;
let canvasHeight = 720;
let rectHeight = 120;
let canvas = document.createElement("canvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
let context = canvas.getContext("2d");
context.rect(0, 0, canvas.width, canvas.height);
let backgroundImg = new Image();
backgroundImg.src = activeData.poster + '?v=' + Math.random(); // 加个随机数防止画布被污染,这个很重要
backgroundImg.crossOrigin = 'Anonymous'; // 加允许跨域,这个也很重要
backgroundImg.onload = function () {
context.drawImage(backgroundImg, 0, 0, canvasWidth, canvasHeight - rectHeight);
// 画矩形
context.fillStyle = "#FFFFFF";
context.strokeStyle = "#bab9b9";
context.lineWidth = 1;
context.fillRect(0, canvasHeight - rectHeight, canvasWidth, 120)
context.strokeRect(0, canvasHeight - rectHeight, canvasWidth, 118);
// 画文本
context.font = "16px bold microsoft";
context.fillStyle = "#000000";
context.fillText(posterData.name, 105, canvasHeight - 70);
context.fillText("向你推荐", 105, canvasHeight - 40);
// 画二维码
context.drawImage($(qrcodeId).children()[0], canvasWidth * 0.75, canvasHeight - 106, 90, 90);
// 头像
let headImg = new Image();
headImg.src = posterData.img + '?v=' + Math.random(); // 加个随机数防止画布被污染,这个很重要
headImg.crossOrigin = 'Anonymous'; // 加允许跨域,这个也很重要
headImg.onload = function () {
// 画圆形头像
drawHeadImg(context, headImg, 80, 80, 12, canvasHeight - 100);
try {
let base64 = canvas.toDataURL("image/png"); //"image/png" 这里注意一下
$("#imageBox").attr("src",base64);
$('#loading').css('display','none');
} catch (error) {
console.log(error);
}
}
}
}
// 画圆形头像
function drawHeadImg(ctx, img, width, height, x, y) {
ctx.save()
let min = Math.min(width, height)
let circle = {
x: Math.floor(min / 2),
y: Math.floor(min / 2),
r: Math.floor(min / 2)
}
ctx.fillStyle = ctx.createPattern(img, 'no-repeat')
ctx.beginPath()
// 开始路径画圆,剪切处理
ctx.arc(circle.x + x, circle.y + y, circle.r, 0, Math.PI * 2, false);
ctx.clip()
// 画圆形头像,且不被切割
ctx.drawImage(img, x, y, 2 * circle.r, 2 * circle.r)
}
</script>
最终实现效果:
公众号:皮蛋馅儿,不定期更新文章,一起学习(^U^)ノ~YO