美文网首页
今日头条文字渐变特效项目实战(一):文字绘制

今日头条文字渐变特效项目实战(一):文字绘制

作者: bug音音 | 来源:发表于2020-12-24 16:12 被阅读0次

    前言

    上篇文章介绍了一些使用Paint和Shader结合实现的一些特效,不过都是一些图像绘制方面的,当然,Paint除了能够进行图像绘制之外,还有另外一个功能,就是文字的绘制

    当然,在学习Paint绘制文字之前,最好能够熟悉一些Paint绘制文字的api这是Paint绘制文字的常用api说明

    1 文字的基线

    说到文字绘制,先从一个api说起

    drawText(@NonNull String text, float x, float y, @NonNull Paint paint)
    
    

    这是一个常用的绘制文字的办法,可能有朋友会遇到,在使用这个方法绘制文字的时候,文字的位置经常不对,不是高了,就是低了,这就是由于这个api中的x和y造成的

    看图说明

    image

    在我们绘制文字的时候,通常有上图中的六条线,分别是

    1. top:顶点线
    2. ascent:建议顶点线
    3. center:中心线
    4. baseline:基线
    5. descent:建议底部线
    6. bottom:底部线

    这六条线分别起什么作用呢?

    • 首先是top和bottom,这两条线很好理解,它分别是顶端和底端,绘制文字时肯定不会超过这两条线
    • 然后是ascent和descent,这两条线是建议的顶点线和建议底端线,一般情况我们绘制文字是不会超过这两条线的,但是对于一些异形字(论坛中经常出现的跨楼层的字)是可以超出这两条线的
    • 再则是center线,这条线也很好理解,它就是top和bottom的中心
    • 最后就是基线了,这也是我们绘制文字时,传入的y坐标

    1.1 基线的计算

    解释了上面六条线的作用,接下来再说说这六条线是怎么计算的。

    首先,我们要清楚,这六条线都是真实存在的,它们的值就保存在Paint.FontMetricsPaint.FontMetricsInt中,这两个类的值基本相似,区别是一个是float,一个是int

    如图

    • Paint.FontMetrics

      image
    • Paint.FontMetricsInt

      image

    明确了这六条线值的位置,那它们是怎么计算得来的呢?

    首先说明,计算着六条线的时候,是以基线为参照物的,计算方式如下

    注:在以下计算推断中,ascent,desent之类的都表示距离,ascent.y,desent.y之类的表示坐标

    top.y = top.y - baseline.y
    bottom.y = bottom.y - baseline.y
    ascent.y = ascent.y - baseline.y
    desent.y = desent.y - baseline.y
    center.y = (bottom.y - top.y) / 2
    
    

    因为是以baseline为参照物,所以所有的距离都是它们的y坐标和baseline的y坐标相减,
    但是Paint.FontMetrics中并没有baseline的值,那么我们要怎么得到它呢

    baseline的计算如图所示(网上好多图都是错的,不得不自己画了一张,(╥﹏╥))

    image

    首先,如果我们要绘制文本,那么我们可以拿到top和bottom的坐标,并且我们也知道center

    • center.y = (bottom.y - top.y) / 2

    看图,我们知道top.y到center.y的距离和bottom.y到center.y的距离相同,设定这个距离为a,那么center.y到baseline.y的距离就是:a - bottom
    (没有.y时表示它到baseline的距离)

    所以有:

    • baseline.y - center.y = (bottom.y - top.y) / 2 - bottom.y

    解得:

    • baseline.y = center.y + (bottom.y - top.y) / 2 - bottom.y

    当然,同样的推理,还可以得出baseline和ascent,desent之间的关系,这里就不展开了,原理都是一样的

    1.2 如何绘制文字到中心

    经历了前面的长篇大论,有的同学就要问了,知道baseline的计算有什么用呢?

    回到最开始的api

    drawText(@NonNull String text, float x, float y, @NonNull Paint paint)
    
    

    是不是有的同学在使用这个api的时候,经常遇到y值怎么设置都不能让文字处于控件中间,不是高一点就是低一点?

    如果我们想把文字绘制到我们View的正中心,那么这里的y就需要传入我们计算好的baseline,代码如下

    // 首先设置paint的文字大小
    paint.setColor(textColor);
    paint.setStrokeWidth(0);
    paint.setTextSize(textSize);
    paint.setTypeface(Typeface.DEFAULT_BOLD);
    
    //根据paint的文字大小获得Paint.FontMetricsInt
    Paint.FontMetricsInt fm = paint.getFontMetricsInt();
    
    //根据Paint.FontMetricsInt计算baseline
    canvas.drawText(string, getWidth() / 2 - paint.measureText(string) / 2 ,
                getHeight() / 2  +(fm.bottom - fm.top)/2 - fm.bottom, paint);
    
    

    这样,就可以将文字画到垂直方向的正中心了,至于水平中心,只需要控件宽度减去文字宽度除以2就可以了

    本来还想写一些文字的特效的,想来篇幅太长阅读起来体验也不太好,文字的特效就留到以后写吧

    相关文章

      网友评论

          本文标题:今日头条文字渐变特效项目实战(一):文字绘制

          本文链接:https://www.haomeiwen.com/subject/vavbnktx.html