-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSquigglyDrawable.java
124 lines (102 loc) · 3.39 KB
/
SquigglyDrawable.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
package com.brar.squigglydrawable;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.view.animation.LinearInterpolator;
import android.view.animation.PathInterpolator;
import androidx.annotation.FloatRange;
public class SquigglyDrawable extends Drawable {
public static float TWO_PI = (float) (Math.PI * 2f);
public static float SEGMENTS_PER_WAVELENGTH = 10;
public float waveLength = 72f;
public float lineAmplitude = 8f;
public float lineAmplitudeSpeed = .25f;
public float phaseSpeed = .5f;
public float phaseOffset = 0f;
public float strokeWidth = 8f;
private Paint paint = new Paint();
private Path squigglyPath = new Path();
private boolean animate = true;
private ValueAnimator phaseAnimator;
public SquigglyDrawable() {
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.BLUE);
paint.setStrokeWidth(strokeWidth);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeJoin(Paint.Join.ROUND);
initPhaseAnimator();
}
//Copied and Translated to java From [saket/extended-spans](https://github.com/saket/extended-spans)
@Override
public void draw(Canvas canvas) {
Rect bounds = getBounds();
float lineStart = bounds.left + strokeWidth;
float lineEnd = (bounds.right - strokeWidth);
float centerY = bounds.bottom / 2f;
float segmentWidth = waveLength / SEGMENTS_PER_WAVELENGTH;
int numOfPoints = (int) Math.ceil((lineEnd - lineStart) / segmentWidth) + 1;
float pointX = lineStart;
for (int point = 0; point < numOfPoints; point++) {
float proportionOfWavelength = (pointX - lineStart) / waveLength;
float radiansX = proportionOfWavelength * TWO_PI + (TWO_PI * phaseOffset);
float offsetY = centerY + (float) (Math.sin(radiansX) * lineAmplitude);
if (point == 0) {
squigglyPath.moveTo(pointX, offsetY);
} else {
squigglyPath.lineTo(pointX, offsetY);
}
pointX = Math.min(pointX + segmentWidth, lineEnd);
}
canvas.drawPath(squigglyPath, paint);
}
public static float lerp(float start, float stop, float amount) {
return start + (stop - start) * amount;
}
@Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
paint.setColorFilter(colorFilter);
}
@Deprecated
@Override
public int getOpacity() {
return paint.getAlpha();
}
void initPhaseAnimator() {
phaseAnimator = ValueAnimator.ofFloat(0f, 1f);
phaseAnimator.setDuration(1000);
phaseAnimator.setInterpolator(new LinearInterpolator());
phaseAnimator.setRepeatCount(ValueAnimator.INFINITE);
phaseAnimator.setRepeatMode(ValueAnimator.RESTART);
phaseAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator arg) {
phaseOffset = (float) phaseAnimator.getAnimatedValue();
squigglyPath.reset();
invalidateSelf();
}
});
phaseAnimator.start();
}
public void setWaveLength(float arg){
this.waveLength = arg;
}
public void setLineAmplitude(float arg){
this.lineAmplitude = arg;
}
public void setPhaseSpeed(float arg){
this.phaseSpeed = arg;
}
public void setStrokeWidth(float arg){
this.strokeWidth = arg;
}
}