近期的项目里用到了一个 绘制 录取通知书的功能 我想到使用canvas 来绘制 顺便记录一下遇到的问题
写一个 画布组件 这个组件带有 width 和 height 属性 用来设置 宽高 id用于获取document元素
<canvas id="canvas" width="800" height="516"></canvas>
然后就是 获取元素并创建上下文对象
let canvas;
let ctx;
canvas = document.getElementById('canvas');
//上下文对象
ctx = canvas.getContext('2d');
//使用vue 的话 讲变量声明在最外层 并在 初始化完成之后获取
//vue3 onMounted
onMounted(()=>{
//确保组件以及渲染 之后再获取元素
nextTick(()=>{
draw();
})
})
function draw(){
canvas = document.getElementById('canvas');
//上下文对象
ctx = canvas.getContext('2d');
}
绘制图像
image图像 x y 图像在画布的坐标 width height 图像绘制的宽高
ctx.drawImage(image, x, y, width, height);
需要注意的是 image 需要时一个img元素
img 可以是document.getElement... 获取html 中的元素
也可以通过 new Image() 创建
let image = new Image();
//图片加载完成的回调
image.onload = () => {
ctx.drawImage(image, x, y, width, height);
}
//给image的src属性赋值 赋值之后等图片加载完成 调用 onload回调 完成绘制
image.src = 'http://......' 图片链接 也可以是本地引入的图片资源 注意不能使用本地路径
需要注意 canvas 绘制 是后面绘制覆盖前面的
而图片加载是一个异步的功能
如果你需要绘制多个图片需要前面绘制的图片绘制完成之后再去绘制下一张图像 不然可能出现 一些需要显示在上方的图像 因为加载速度原因 被遮盖
我的解决方案为
let canvas;
let ctx;
async function draw(){
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
// 此处img 是一个图片链接
await drawImg(img, 67, 251, 133, 186);
//await 等待前面图像绘制完成之后再开始绘制下一张 保证绘制元素的显示层级
await drawImg(img, 10, 10, 120, 133);
...绘制其他元素
}
function drawImg(img, x, y, width, height){
return new Promise((resolve, reject) => {
let image = new Image();
image.onload = () => {
ctx.drawImage(image, x, y, width, height);
resolve();
};
image.src = img;
});
}
绘制文字
function drawText(){
//设置文字的样式
ctx.font = '20px Arial';
//设置文字的颜色
ctx.fillStyle = '#333333';
//绘制文字
ctx.fillText('绘制内容', 380, 285);
}
如果你后续需要绘制其他样式的文字 重新设置文字样式 然后绘制就可以了
function drawText(){
//绘制粗体文字
ctx.font = 'bold 30px Arial';
ctx.fillStyle = 'red';
ctx.fillText('文字', 380, 285);
}
绘制线条
//线条的颜色
ctx.strokeStyle = 'black';
//宽度
ctx.lineWidth = 1;
// 开始新的线条绘制
ctx.beginPath();
// 线条的起始位置
ctx.moveTo(startX, startY);
//线条的结束位置
ctx.lineTo(endX, endY);
//绘制
ctx.stroke();
//封装函数
function drawLine(startX, startY, endX, endY){
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.stroke();
}
转为图片并下载
//创建一个 a标签
const el = document.createElement('a');
//将绘制好的canvas 转换为图像链接 base64格式
el.href = canvas.toDataURL('image/png');
//设置元素下载名称
el.download = '录取通知书.png';
//触发点击时间开始下载
el.click();