有个项目需求是生成带二维码的邀请卡片,效果图如下:
思路
先说下实现思路:
- 使用canvas的drawImage、fillText进行图片、文字的合成
- 使用html2canva插件实现对DOM的截图,前提是有这个邀请卡片的HTML
思路1实现
先实现一个简单的Demo,需要以下物料:
头像和二维码先用静态的做演示。。。有需要可以使用qrcode生成二维码。
步骤:
- 新建canvas标签
- 获取canvas上下文 canvas.getContext('2d')
- new Image() ctx.drawImage 绘制背景图
- 绘制头像
- ctx.fillText绘制用户名
- 绘制二维码
- 将图像的src改为对应的物料
- 使用canvas.toDataURL得到base64
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas合成名片</title>
<style>
#previewContainer {
margin-top: 20px;
text-align: center;
display: none;
}
#previewImage {
max-width: 100%;
max-height: 80vh;
border: 1px solid #ddd;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
</style>
</head>
<body>
<button id="generateBtn">生成邀请名片</button>
<button id="previewBtn">预览邀请名片</button>
<canvas id="canvas" style="display:none;"></canvas>
<div id="previewContainer">
<h3>预览效果</h3>
<img id="previewImage" alt="邀请名片预览">
<br><br>
<button id="downloadBtn">下载名片</button>
</div>
<script>
// 存储合成的图片数据
let generatedImageData = null;
// 预览按钮事件
document.getElementById('previewBtn').addEventListener('click', function() {
generateCard(true); // 生成并显示预览
});
// 生成按钮事件
document.getElementById('generateBtn').addEventListener('click', function() {
generateCard(false); // 生成并直接下载
});
// 下载按钮事件
document.getElementById('downloadBtn').addEventListener('click', function() {
if (generatedImageData) {
downloadImageFromData(generatedImageData);
}
});
// 生成名片主函数
function generateCard(isPreview) {
// 创建canvas元素
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// 设置画布尺寸
canvas.width = 1170;
canvas.height = 3558;
// 创建背景图
const background = new Image();
background.onload = function() {
// 绘制背景图
ctx.drawImage(background, 0, 0, canvas.width, canvas.height);
// 加载头像
const avatar = new Image();
avatar.onload = function() {
// 设置头像位置和尺寸
const avatarWidth = 240;
const avatarHeight = 240;
const avatarX = (canvas.width - avatarWidth) / 2; // 居中
const avatarY = 1300; // 距离顶部1460px
// 绘制头像
ctx.drawImage(avatar, avatarX, avatarY, avatarWidth, avatarHeight);
// 在头像旁边添加文字
ctx.fillStyle = '#FFF'; // 文字颜色
ctx.font = 'bold 48px Arial'; // 字体样式
ctx.textAlign = 'center'; // 文字对齐方式
ctx.fillText('陈*文', canvas.width/2, avatarY + avatarHeight + 70); // 用户名
// 加载二维码
const qrcode = new Image();
qrcode.onload = function() {
// 设置二维码位置和尺寸
const qrWidth = 400;
const qrHeight = 400;
const qrX = (canvas.width - qrWidth) / 2; // 居中
const qrY = 1840; // 距离顶部1840px
// 绘制二维码
ctx.drawImage(qrcode, qrX, qrY, qrWidth, qrHeight);
// 合成完成后的处理
if (isPreview) {
// 显示预览
showPreview(canvas);
} else {
// 直接下载
downloadImage(canvas);
}
};
qrcode.src = './assets/qr.png'; // 替换为您的二维码图片路径
};
avatar.src = './assets/avatar.png';
};
background.src = './assets/bg.png';
}
// 显示预览
function showPreview(canvas) {
const previewImage = document.getElementById('previewImage');
const previewContainer = document.getElementById('previewContainer');
// 保存图像数据供下载使用
generatedImageData = canvas.toDataURL('image/png');
// 设置预览图像
previewImage.src = generatedImageData;
// 显示预览容器
previewContainer.style.display = 'block';
}
// 下载合成图片
function downloadImage(canvas) {
const link = document.createElement('a');
link.download = 'invitation-card.png';
link.href = canvas.toDataURL('image/png');
link.click();
}
// 从数据URL下载图片
function downloadImageFromData(dataURL) {
const link = document.createElement('a');
link.download = 'invitation-card.png';
link.href = dataURL;
link.click();
}
</script>
</body>
</html>
使用qrcode
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas合成名片</title>
<!-- 引入qrcode.js库 -->
<script src="https://cdn.jsdelivr.net/npm/qrcode/build/qrcode.min.js"></script>
<style>
#previewContainer {
margin-top: 20px;
text-align: center;
display: none;
}
#previewImage {
max-width: 100%;
max-height: 80vh;
border: 1px solid #ddd;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
</style>
</head>
<body>
<button id="generateBtn">生成邀请名片</button>
<button id="previewBtn">预览邀请名片</button>
<canvas id="canvas" style="display:none;"></canvas>
<div id="previewContainer">
<h3>预览效果</h3>
<img id="previewImage" alt="邀请名片预览">
<br><br>
<button id="downloadBtn">下载名片</button>
</div>
<script>
// 存储合成的图片数据
let generatedImageData = null;
// 预览按钮事件
document.getElementById('previewBtn').addEventListener('click', function() {
generateCard(true); // 生成并显示预览
});
// 生成按钮事件
document.getElementById('generateBtn').addEventListener('click', function() {
generateCard(false); // 生成并直接下载
});
// 下载按钮事件
document.getElementById('downloadBtn').addEventListener('click', function() {
if (generatedImageData) {
downloadImageFromData(generatedImageData);
}
});
// 生成名片主函数
function generateCard(isPreview) {
// 创建canvas元素
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// 设置画布尺寸
canvas.width = 1170;
canvas.height = 3558;
// 创建背景图
const background = new Image();
background.onload = function() {
// 绘制背景图
ctx.drawImage(background, 0, 0, canvas.width, canvas.height);
// 加载头像
const avatar = new Image();
avatar.onload = function() {
// 设置头像位置和尺寸
const avatarWidth = 240;
const avatarHeight = 240;
const avatarX = (canvas.width - avatarWidth) / 2; // 居中
const avatarY = 1300; // 距离顶部1460px
// 绘制头像
ctx.drawImage(avatar, avatarX, avatarY, avatarWidth, avatarHeight);
// 在头像旁边添加文字
ctx.fillStyle = '#FFF'; // 文字颜色
ctx.font = 'bold 48px Arial'; // 字体样式
ctx.textAlign = 'center'; // 文字对齐方式
ctx.fillText('陈*文', canvas.width/2, avatarY + avatarHeight + 70); // 用户名
// 使用qrcode插件生成二维码
generateQRCode(function(qrCanvas) {
// 设置二维码位置和尺寸
const qrWidth = 400;
const qrHeight = 400;
const qrX = (canvas.width - qrWidth) / 2; // 居中
const qrY = 1840; // 距离顶部1840px
// 绘制二维码
ctx.drawImage(qrCanvas, qrX, qrY, qrWidth, qrHeight);
// 合成完成后的处理
if (isPreview) {
// 显示预览
showPreview(canvas);
} else {
// 直接下载
downloadImage(canvas);
}
});
};
avatar.src = './assets/avatar.png';
};
background.src = './assets/bg.png';
}
// 使用qrcode.js生成二维码
function generateQRCode(callback) {
// 创建临时canvas用于生成二维码
const tempCanvas = document.createElement('canvas');
// 使用qrcode库生成二维码
QRCode.toCanvas(tempCanvas, 'https://opening.wlbank.tech/zh_hk/biz/mgm?Ref_no=0000006327', {
width: 400,
height: 400,
margin: 2,
color: {
dark: '#000000',
light: '#ffffff'
}
}, function (error) {
if (error) {
console.error('生成二维码失败:', error);
return;
}
// 生成成功后回调
callback(tempCanvas);
});
}
// 显示预览
function showPreview(canvas) {
const previewImage = document.getElementById('previewImage');
const previewContainer = document.getElementById('previewContainer');
// 保存图像数据供下载使用
generatedImageData = canvas.toDataURL('image/png');
// 设置预览图像
previewImage.src = generatedImageData;
// 显示预览容器
previewContainer.style.display = 'block';
}
// 下载合成图片
function downloadImage(canvas) {
const link = document.createElement('a');
link.download = 'invitation-card.png';
link.href = canvas.toDataURL('image/png');
link.click();
}
// 从数据URL下载图片
function downloadImageFromData(dataURL) {
const link = document.createElement('a');
link.download = 'invitation-card.png';
link.href = dataURL;
link.click();
}
</script>
</body>
</html>
物料
物料在这里,感兴趣的伙伴可以试试!