目录java
1、前言git
2、Canvas中的书法家APIgithub
3、实战canvas
4、写在最后微信
canvas 的 API 方法至关之多,小盆友本篇文章以前已经分享了 “Canvas中的裁剪师” 和 “Canvas中的绘图师”,今天分享的是文字方面的API。ide
在分享前,小盆友啰嗦两句,有些童鞋说 canvas 的这几篇文章是初级文章和 “Android高级UI” 这几个字显得有些格格不入。小盆友借此解释下,canvas 的这几篇文章是做为 高级UI 文章的补充,是这系列文章中的 垫脚石,并不是想作 “标题党” 来吸引流量(貌似一直也没什么流量😂)。函数
啰嗦了这么多,来看看今天的实战效果图post
抖动的字符 动画
(1)第一个 drawText 函数编码
public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) 复制代码
描述: 在坐标为 (x,y) 处绘制 text 字符串。
举个例子:
private static final String CONTENT = "zinc 猛猛的小盆友";
canvas.drawText(CONTENT, -300, -500, mPaint);
复制代码
效果图
public void drawText(@NonNull String text, int start, int end, float x, float y, @NonNull Paint paint) 复制代码
描述: 在坐标为 (x,y) 处绘制字符串text,从下标为start的字符开始,到下标为 (end-1) 的字符终止。
举个例子:
private static final String CONTENT = "zinc 猛猛的小盆友";
// 绘制内容为从CONTENT的第四个字符开始,到CONTENT最后一个字符
canvas.drawText(CONTENT, 3, CONTENT.length(), -300, -400, mPaint);
复制代码
效果图
public void drawText(@NonNull char[] text, int index, int count, float x, float y, @NonNull Paint paint) 复制代码
描述: 在坐标为 (x,y) 处绘制 text,从下标为start开始,绘制count个字符。
举个例子
private static final char[] C = "https://github.com/zincPower/UI2018".toCharArray();
canvas.drawText(C, 0, C.length, -300, -100, mPaint);
canvas.drawText(C, 5, 10, -300, 0, mPaint);
复制代码
效果图
public void drawText(@NonNull CharSequence text, int start, int end, float x, float y, @NonNull Paint paint) 复制代码
描述: 在坐标为 (x,y) 处绘制 text,从下标为start的字符开始,到下标为 (end-1) 的字符终止。
举个例子
private static final CharSequence SEQ = "https://blog.csdn.net/weixin_37625173";
canvas.drawText(SEQ, 0, SEQ.length(), -300, 300, mPaint);
canvas.drawText(SEQ, 6, 20, -300, 400, mPaint);
复制代码
效果图
(1)第一个 drawTextOnPath 函数
public void drawTextOnPath(@NonNull String text, @NonNull Path path, float hOffset, float vOffset, @NonNull Paint paint) 复制代码
描述: 在 路径path 上绘制 text。
特殊参数说明: 1)hOffset:水平偏移量 2)vOffset:垂直偏移量
举个例子
private static final String CONTENT = "zinc 猛猛的小盆友";
// mPath 是一个贝塞尔曲线绘制的路径
canvas.drawTextOnPath(CONTENT, mPath, 0, 0, mPaint);
复制代码
效果图
public void drawTextOnPath(@NonNull char[] text, int index, int count, @NonNull Path path, float hOffset, float vOffset, @NonNull Paint paint) 复制代码
描述: 在 路径path 上绘制 text。
特殊参数说明: 1)index:从下标为index的字符开始绘制 2)count:绘制字符的个数 3)hOffset:水平偏移量 4)vOffset:垂直偏移量
例子
private static final char[] C = "https://blog.csdn.net/weixin_37625173".toCharArray();
// 从下标为2的字符(即第三个字符)开始,绘制20个字符
canvas.drawTextOnPath(C, 2, 20, mPath, 0, 0, mPaint);
复制代码
效果图
这个方法不作过多的解释,由于在实际开发中使用能够说较少。简单归纳这个方法的做用,他是为了处理一些语言文字(例如:阿拉伯语),当一个字在一个词语中,会受左右的字影响而进行变形的状况。
这方面的语言小盆友不懂,因此无法举出严谨的例子,请有须要的童鞋移步Demo中自行体会。
public void drawTextRun(@NonNull char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, boolean isRtl, @NonNull Paint paint) public void drawTextRun(@NonNull CharSequence text, int start, int end, int contextStart, int contextEnd, float x, float y, boolean isRtl, @NonNull Paint paint) 复制代码
(1)第一个 drawPosText 函数
public void drawPosText(@NonNull String text, @NonNull @Size(multiple = 2) float[] pos, @NonNull Paint paint) 复制代码
描述: 在pos对应的坐标上绘制text。
举个例子
private static final String CONTENT = "猛猛的小盆友";
private static final float[] pos1 = new float[]{
-300, -600,
-250, -500,
-200, -400,
-150, -300,
-100, -200,
-50, -100,
};
// 每一个字符 和 pos的坐标要一一对应的上,不然crash
canvas.drawPosText(CONTENT, pos1, mPaint);
复制代码
效果图
public void drawPosText(@NonNull char[] text, int index, int count, @NonNull @Size(multiple = 2) float[] pos, @NonNull Paint paint) 复制代码
描述: 在pos对应的坐标上绘制text,从下标为index的字符开始,绘制count个。
举个例子
private static final String CONTENT = "猛猛的小盆友";
private static final float[] pos2 = new float[]{
-300, 100,
-250, 200,
-200, 300,
-150, 400,
-100, 500,
};
canvas.drawPosText(CONTENT.toCharArray(), 1, 4, pos2, mPaint);
复制代码
效果图
抖动的字符
Github入口:传送门
编码思路 在这一实战中,其实 drawTextOnPath
反倒不是主角,他只是负责在咱们的 path 上将文字绘出便可,因此童鞋们知道了最主要的是 path 的肯定。
获取 path 上的点,是经过以下的函数获取
private float calculateY(float x) {
double a = Math.pow(4 / (4 + Math.pow(4 * x / mLength, 4)), 2.5f) * mA;
return (float) (a * Math.sin(Math.PI * x / 200 - m));
}
复制代码
具体的函数图形以下
公式的最初原型来源于此博客,在此谢谢博主。
看完这函数,可能有些童鞋比较懵逼,小盆友稍微给一些简单解释(毕竟难的我也说不清😂),咱们将此公式抽象一下,即是以下形状:
A*sin(w*x+m)+k
复制代码
这就是咱们在初中学的三角函数:正弦函数sin。咱们罗列下几个参数的做用:
在咱们这里的场景中,主要控制两个参数:
让字符串摇摆起来 通过上面的简单分析,咱们须要的各类零件也都准备好了,最后加入咱们再熟悉不过的 属性动画,就可让这条 路径path 动起来。路径path 动起来,会致使绘制在上面文字也动起来。
mAnimator = ValueAnimator.ofFloat(0, (float) (2 * Math.PI));
mAnimator.setInterpolator(new LinearInterpolator());
mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float progress = (float) animation.getAnimatedValue();
m = progress;
mA = (float) (1 - progress / (2 * Math.PI)) * A;
invalidate();
}
});
mAnimator.setDuration(1000);
复制代码
此次的文章较为简单和基础,只是小盆友有点强迫症,必需要把 canvas 的每一个API都过一遍和记录一下。
若是以为文章对你有所启发,请给我个赞吧,若是发现有那些欠妥的地方,请留言区与我讨论,咱们共同进步。
高级UI系列的Github地址:请进入传送门,若是喜欢的话给我一个star吧😄
欢迎加我微信,咱们能够进行更多更有趣的交流