目錄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吧😄
歡迎加我微信,咱們能夠進行更多更有趣的交流