首先是什么原因接触这个技术栈呢,
首先产品突然来个需求,说要点击按钮下载一个海报图,提供背景图,背景图上的数据是后端返回, 一开始告诉产品,不能实现,然后另一个前端同事说可以用canvas做到,一脸懵逼的我(我擦,还有这种操作,还是知识面不够广啊,然后赶紧去度娘研究)
定义ctx对象
let cvs = document.createElement('canvas');
let ctx = cvs.getContext('2d');
我是在页面上定义了一个canvas标签,id为canvas
这个是所有开始画canvas必须做的,getContext() 方法返回一个用于在画布上绘图的环境。
设置下载图的宽高
cvs.width = 1240;
cvs.height =1753;
这个比较简单,跟html差不多
设置背景图
var img=document.getElementById("scream");
ctx.drawImage(img,0,0);
在html写个img标签,id为scream,src为你要的图片地址
这个也比较简单,drawImage方法接收3个参数,第二,第三个参数为离左上角的距离
画圆角矩形
个人觉得这个点是画图最难的一个点,百度了很多,但是没找到有直接画矩形带设置类似html border-radius的api,然后去百度啊,经过朋友的帮忙,找到了一个封装的方法,如下
参数说明:
ctx:ctx对象,这个没什么好说 x:离x轴的距离
y: 离y轴的距离
width:矩形的宽
height:矩形的高
radius:类似css的border-radius属性,值为数字
fill:是否填充背景,值为true或者false
stroke:是否有边框阴影,值为true或者false
function strokeRoundRect(ctx, x, y, width, height, radius, fill, stroke,fillStyle){
if (typeof stroke == 'undefined') {
stroke = true;
}
if (typeof radius === 'undefined') {
radius = 5;
}
if (typeof radius === 'number') {
radius = {tl: radius, tr: radius, br: radius, bl: radius};
} else {
var defaultRadius = {tl: 0, tr: 0, br: 0, bl: 0};
for (var side in defaultRadius) {
radius[side] = radius[side] || defaultRadius[side];
}
} ctx.beginPath();
ctx.moveTo(x + radius.tl, y);
ctx.lineTo(x + width - radius.tr, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius.tr);
ctx.lineTo(x + width, y + height - radius.br);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius.br, y + height);
ctx.lineTo(x + radius.bl, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius.bl);
ctx.lineTo(x, y + radius.tl);
ctx.quadraticCurveTo(x, y, x + radius.tl, y);
ctx.fillStyle=fillStyle;
ctx.closePath();
if (fill) {
ctx.fill();
}
if (stroke) {
ctx.stroke();
}
}
画倒三角形
ctx.beginPath
var height = 60*Math.sin(Math.PI/3);//计算等边三角形的高
ctx.moveTo(620,1220); //从哪个坐标开始画
ctx.lineTo(590,height+1120);//B点,从A(100,0)开始,画到B 点结束
ctx.lineTo(650,height+1120); //C点,B坐标到C坐标
ctx.fillStyle='#fff';//背景色设置白色
ctx.fill(); //闭合形状并且以填充方式绘制出来
设置文字
ctx.font="47px 思源黑体";
ctx.fillStyle ="#f0d748";
ctx.textAlign = 'center';
ctx.textBaseline='middle';//文本垂直方向,基线位置
ctx.fillText("文字",620,292);
总结
canvas一定要按顺序画,不然后面的会覆盖前面的内容,用canvas,感觉画坐标调试很麻烦, emmmmmm。。。从此不想再碰canvas的心都有
第一次在掘金写文章,比较简短,如有不足,请各位大佬多提下意见~~~