本文介绍了生成海报的各种方法,以及canvas插入图片浏览器跨域问题。
手工拼接canvas
最近的几个需求全都需要生成海报,后端那边没有现成的生成海报的方法还不可控,所以就由前端生成海报
生成海报肯定就离不开canvas,如果不是很复杂的海报就完全可以手动拼接然后生成base64格式,最后下载。
具体的操作步骤就是先在canvas上吧背景文字都插入好,然后通过toDataURL( 'image/png' )方法实现转化,转化后就是一张图片了,想怎么用就怎么用
generatePosterShoudong() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d")
var img = new Image()
var haibaoUrl = ''
img.onload = function() {
ctx.drawImage(img, 0, 0, 750, 1334)
// 插入二维码
var qrcode = new Image();
qrcode.src = qrCodeBase64 // 这里的二维码用的是toqrcode的插件
qrcode.onload = function() {
ctx.drawImage(qrcode, 517, 1028, 160, 160)
}
// 插入名字文字
ctx.font = "40px Arial"
ctx.fillStyle = '#FFF'
ctx.fillText('用户AAA',178,87);
// 插入名字文字
ctx.font = "32px Arial"
ctx.fillStyle = '#FFF'
ctx.fillText("邀请你免费领礼包",178,137);
// 插入头像
var head = new Image();
head.src = headBase64
head.onload = function() {
ctx.save()
ctx.arc(100, 100, 48, 0, Math.PI * 2, false); // 生成圆角头像
ctx.clip()
ctx.drawImage(head, 50, 50, 98, 98)
ctx.restore()
haibaoUrl = canvas.toDataURL( 'image/png' )// 这里就是拼好的海报base64了
}
}
img.src = haibaoUrl
}
跨域问题
由于浏览器的同源策略,直接引入图片链接是会爆同源策略的报错的,所以就需要用到原始的图片格式base64,只要拿到了base64各式,图片就会任你摆布。
我这里用到的方法是后端提供url转base64的接口,要拼接之前先去后端调用一下。
还用一种方法是把要用到的图片先转换好,推荐菜鸟教程的这个网站,在线转base64,转换速度还是很快的,然后把它以json格式传到项目的静态资源库,像是这样:
然后按照get请求一样调用就好了,也不需要后端,也减少了前端的负担,两全其美😄。
还有一个通用的图片转base64的方法,如果你的图片和项目在一个源下,就可以直接前端转换。
convertImgToBase64(url, callback, outputFormat){
var canvas = document.createElement('CANVAS'),
ctx = canvas.getContext('2d'),
img = new Image;
img.crossOrigin = 'Anonymous';
img.onload = function(){
canvas.height = img.height;
canvas.width = img.width;
ctx.drawImage(img,0,0);
var dataURL = canvas.toDataURL(outputFormat || 'image/png');
callback.call(this, dataURL);
canvas = null;
};
img.src = url;
}
点击直接下载到本地
创建一个a链接模拟点击就会直接下载到本地(仅PC有效)
var a = document.createElement('a')
a.href = canvas.toDataURL( 'image/png' )
a.download = '千图分享海报' // 设定下载名称
a.click()
直到这里基本上已经可以生成海报了,还有一个引入组件html2canvas实现更复杂的生成海报,他的工作原理就是吧网站上的html转给它,他就会生成对应的canvas,功能比较强大。
首先需要官网引入js文件: html2canvas,然后调用方法把html传进去就好了。
这里依然会出现跨域问题,所以还是要用到上面的转换base64的方法。
html2canvas
html2canvas(document.querySelector("#capture")).then(canvas => {
//canvas就是生成好的canvas
let href = canvas.toDataURL('image/png') // 将画布内的信息导出为png图片数据
this.imgBase64 = href
});