前情提要
UI小哥给了一张UI图,让我实现小程序的分享海报

踩坑如下:
- canvas绘制文字自动换行
- canvas绘制文字,首行缩进
- canvas剪切圆形头像
一、canvas 绘制文字,自动换行
因为canvas.fillText绘制文字是没用自动换行的功能的,所以需要自己封装个函数来实现。
canvas有个APIctx.measureText(string str).width可以获取字符串的像素长度
当一行文字的像素长度超过画布的长度时,就可以另起一行重新绘制文字
/*
lineWidth:一行文字的总长度
str:是要写入的字符串
initX:初始时,文字距离画布边缘的距离
canvasWidth:画布的宽度
lineHeight:是行高
*/
let lineWidth = 0;
for(let i=0;i<str.length;i++){
lineWidth += ctx.measureText(str[i]).width;//每次增加一个字符的像素长度
if(lineWidth>canvasWidth-2*initX){
//减去两个initX是想在文字两边都有相同距离的空白
ctx,fillText(str.substr(0,i),initX,initY);
initY+=lineHeight;
str = str.str.substr(i);
i = -i;
lineWidth;
}
//如果绘制到字符串的末尾了,还没超过画布的宽度
if(i==str.length-1){
ctx.fillText(str.substr(0,i+1),initX,initY);
}
}
二、canvas首行缩进
因为canvas没有首行缩进的属性,只能是,绘制的时候,向右偏移两个字符的长度
/*
indent:布尔值,是否缩进
indentWidth:缩进的像素宽度
*/
let indent = true;
let indentWidth = 0;
for(let i=0;i<str.length;i++){
lineWidth += ctx.measureText(str[i]).width;
if(indent && i==1){
indentWidth = lineWidth;
}
if(indent && lineWidth>canvasWidth-2*initX-indentWidth){
ctx.fillText(str.substr(0,i),initX+indentWidth,initY);
initY+=lineHeight;
lineWidth=0;
indent = false;
str = str.substr(i);
i =-1;
}
}
小总结,将自动换行和首行缩进,封装成函数如下
/*
ctx:wx.createCanvasContext获取的画布上下文
initX:距离画布左边缘的距离
initY:距离画布上部的距离
str:要绘制的字符串
lineHeight:行高
indent:布尔值,是否要首行缩进
*/
canvasTextAutoLine(ctx,canvasWidth,str,initX,initY,lineHeight,indent=false){
let lineWidth = 0;
let indentWidth=0;
for(let i=0;i<str.length;i++){
lineWidth += ctx.measureText(str[i]).width;
if(indent && i==1){
indentWidth = lineWidth;
}
if(indent && lineWidth>canvasWidth-2*initX-indentWidth){
ctx.fillText(str.substr(0,i),initX+indentWidth,initY);
initY+=lineHeight;
lineWidth=0;
indent = false;
str = str.substr(i);
i =-1; //下次循环i会加1,所以下次循环就是1
}
if(lineWidth>canvasWidth-2*initX){
ctx.fillText(str.substr(0,i),initX,initY);
initY+=lineHeight;
str=str.substr(i);
i=-1;
lineWidth=0;
}
if(i==str.length-1){
ctx.fillText(str.substr(0,i+1),initX,initY);
}
}
return initY;
}
三、canvas剪切出圆形的头像
canvas的APIctx.clip()可以剪切图形,使用如下
//1. 在使用clip()要先将之前绘制的图形保存
ctx.save();
//2. 绘制你要剪切的图形
ctx.arc(25,25,25,0,Math.PI*2);
//3. 剪切
ctx.clip();
//4. 在剪切的范围内绘制图形,超过这个范围的不显示
ctx.drawImage(headImg,0,0,25,25);
//5. 绘制完后,释放之前保存的图形
ctx.restore();
结语
作者:胡志武
时间:2019/7/17
本人大二,想找个前端实习生的工作。求职中。。。