阅读 416

小程序分享海报的坑

前情提要

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

wxf1357e20f85c21d2.o6zAJs7VwnASgn7-qfIjrekatMsY.NpylDmN4LBp1eb97c458caf0f73908d00884fb06dbc6

踩坑如下:

  1. canvas绘制文字自动换行
  2. canvas绘制文字,首行缩进
  3. 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

本人大二,想找个前端实习生的工作。求职中。。。

关注下面的标签,发现更多相似文章
评论