vue使用canvas合成海报
接着上面随笔,继续探索~~~
上篇合成海报的过程有点负责冗余。完全可以不借助插件,用canvas合成~~
需求背景:多张模版可供选择,用户输入姓名,上传头像,最终合成海报保存分享。
1.头像有黑色边框,可利用背景图剧中显示。用户输入的姓名定位到海报具体位置。
2.上传头像部分通过@change=uploadImg(e),e拿到图片信息。
---先做个判断拦截
//上传图片
var file = e.target.files[0];
if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
this.$toast('图片类型必须是.gif,jpeg,jpg,png,bmp中的一种')
return false;
}
---然后读取图片信息
var reader = new FileReader();
reader.onload = e => { // 该事件是读取完成的时候触发。
this.headSrc = e.target.result // 上传图片
}
reader.readAsDataURL(file) // 读取文件
-------此时用户上传图片已经渲染在页面上
3.合成海报。分三部分,一部分模版,一部分用户输入姓名,一部分用户上传头像
-----
var c = document.createElement("canvas");
var ctx = c.getContext("2d");
c.width = this.pw; // 画布宽
c.height = this.ph; // 画布高
-----
var img = new Image();
img.src = _this.bgurl; // 背景图
img.onload = function() {
ctx.drawImage(img, 0, 0, c.width, c.height);
var img2 = new Image(); // 头像
_this.ClippingImage(_this.heardSrc,1,function(url){
img2.src = url; // 头像
console.log('img2',img2.src,url)
img2.onload = function() {
var d =2 * 58; // 头像圆圈直径
var cx = 545 + 54; // 圆心X轴坐标
var cy = 604 + 54; // 圆心Y轴坐标
ctx.arc(cx, cy, 54, 0, 2 * Math.PI); // 画圆
ctx.clip(); // 闭合圆圈 使后面的作图限制在圆圈内
ctx.drawImage(img2, 545, 604, d, d); // 画头像
ctx.strokeStyle='#c8c8c8'; // 头像描边颜色
ctx.lineWidth=6; // 头像描边宽度
ctx.beginPath(); // 开始画图
ctx.arc(cx, cy, 54, 0, 2 * Math.PI); // 描边绘画
ctx.stroke()
_this.modelSrc = c.toDataURL("image/png", 1);
};
ctx.font = "30px Arial"; // 用户姓名字体样式
ctx.fillStyle="#fff";// 用户姓名字体颜色
ctx.fillText(_this.name,600,580); // 把用户姓名写入具体位置
})
}
4.ClippingImage方法是裁剪用户上传头像的方法。
------
ClippingImage(base64Codes,quality,callback) {
var img = new Image();
img.src = base64Codes;
//生成canvas
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var sX,sY;
img.onload = function () {
if(img.width > img.height) { // 长形
canvas.width = img.height
canvas.height = img.height
sX = (img.width-img.height)/2
sY = 0
} else if (img.width < img.height) { // 竖形
canvas.width = img.width
canvas.height = img.width
sX = 0
sY = (img.height-img.width)/2
} else { // 正方形
canvas.width = img.width
canvas.height = img.width
sX = 0
sY = 0
}
ctx.drawImage(img,sX,sY,canvas.width,canvas.height,0,0,canvas.width,canvas.height);
var base64Result = canvas.toDataURL('image/png', quality);
callback(base64Result)
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?