/
SparkleText.java
128 lines (99 loc) · 4.41 KB
/
SparkleText.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package com.hanks.htextview.animatetext;
import android.animation.ValueAnimator;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import com.hanks.htextview.R;
import com.hanks.htextview.util.CharacterUtils;
import java.util.Random;
/**
* Created by hanks on 15-12-14.
*/
public class SparkleText extends HText {
float progress = 0;
float charTime = 400;
int mostCount = 20;
float upDistance = 0;
private Paint backPaint;
private Bitmap sparkBitmap;
@Override protected void initVariables() {
backPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
backPaint.setColor(((ColorDrawable) mHTextView.getBackground()).getColor());
backPaint.setStyle(Paint.Style.FILL);
sparkBitmap = BitmapFactory.decodeResource(mHTextView.getResources(), R.drawable.sparkle);
}
@Override protected void animateStart(CharSequence text) {
int n = mText.length();
n = n <= 0 ? 1 : n;
long duration = (long) (charTime + charTime / mostCount * (n - 1));
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, duration).setDuration(duration);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override public void onAnimationUpdate(ValueAnimator animation) {
progress = (float) animation.getAnimatedValue();
mHTextView.invalidate();
}
});
valueAnimator.start();
}
@Override protected void animatePrepare(CharSequence text) {
Rect bounds = new Rect();
mPaint.getTextBounds(mText.toString(), 0, mText.length(), bounds);
upDistance = bounds.height();
}
@Override protected void drawFrame(Canvas canvas) {
float offset = startX;
float oldOffset = oldStartX;
int maxLength = Math.max(mText.length(), mOldText.length());
float percent = progress / (charTime + charTime / mostCount * (mText.length() - 1));
mPaint.setAlpha(255);
mPaint.setTextSize(mTextSize);
for (int i = 0; i < maxLength; i++) {
// draw new text
if (i < mText.length()) {
if (!CharacterUtils.stayHere(i, differentList)) {
float width = mPaint.measureText(mText.charAt(i) + "");
canvas.drawText(mText.charAt(i) + "", 0, 1, offset, startY, mPaint);
if (percent < 1) {
drawSparkle(canvas, offset, startY - (1 - percent) * upDistance, width);
}
canvas.drawRect(offset, startY * 1.2f - (1 - percent) * (upDistance + startY * 0.2f), offset + gaps[i], startY * 1.2f, backPaint);
}
offset += gaps[i];
}
// draw old text
if (i < mOldText.length()) {
//
float pp = progress / (charTime + charTime / mostCount * (mText.length() - 1));
mOldPaint.setTextSize(mTextSize);
int move = CharacterUtils.needMove(i, differentList);
if (move != -1) {
mOldPaint.setAlpha(255);
float p = pp * 2f;
p = p > 1 ? 1 : p;
float distX = CharacterUtils.getOffset(i, move, p, startX, oldStartX, gaps, oldGaps);
canvas.drawText(mOldText.charAt(i) + "", 0, 1, distX, startY, mOldPaint);
} else {
float p = pp * 3.5f;
p = p > 1 ? 1 : p;
mOldPaint.setAlpha((int) (255 * (1 - p)));
canvas.drawText(mOldText.charAt(i) + "", 0, 1, oldOffset, startY, mOldPaint);
}
oldOffset += oldGaps[i];
}
}
}
private void drawSparkle(Canvas canvas, float offset, float startY, float width) {
Random random = new Random();
for (int i = 0; i < 8; i++) {
canvas.drawBitmap(getRandomSpark(random), (float) (offset + random.nextDouble() * width), (float) (startY - random
.nextGaussian() * Math.sqrt(upDistance)), mPaint);
}
}
private Bitmap getRandomSpark(Random random) {
int dstWidth = random.nextInt(12) + 1;
return Bitmap.createScaledBitmap(sparkBitmap, dstWidth, dstWidth, false);
}
}