-
-
Save peterkuterna/8917076 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Context; | |
import android.graphics.Canvas; | |
import android.graphics.Color; | |
import android.graphics.Paint; | |
import android.graphics.Path; | |
import android.util.AttributeSet; | |
import android.view.View; | |
import android.view.animation.AccelerateDecelerateInterpolator; | |
import android.view.animation.Interpolator; | |
/** | |
* http://sriramramani.wordpress.com/2013/10/14/number-tweening | |
* <br/> | |
* Note that this is just an example of how you can do number morphing, | |
* you'll still need to modify the View so it can support resizing, | |
* correct update delay, etc. | |
* | |
* <br/> | |
* -added the control points | |
*/ | |
public class NumberMorphingView extends View { | |
private final Interpolator mInterpolator; | |
private final Paint mPaint; | |
private final Path mPath; | |
// Numbers currently shown. | |
private int mCurrent = 0; | |
private int mNext = 1; | |
// Frame of transition between current and next frames. | |
private int mFrame = 0; | |
// The 5 end points. (Note: The last end point is the first end point of the | |
// next segment. | |
private final float[][][] mPoints = { | |
{ { 44.5f, 100 }, { 100, 18 }, { 156, 100 }, { 100, 180 }, { 44.5f, 100 } }, // 0 | |
{ { 77, 20.5f }, { 104.5f, 20.5f }, { 104.5f, 181 }, { 104.5f, 181 }, { 104.5f, 181 } }, // 1 | |
{ { 56, 60 }, { 144.5f, 61 }, { 108, 122 }, { 57, 177 }, { 147, 177 } }, // 2 | |
{ { 63.25f, 54 }, { 99.5f, 18 }, { 99.5f, 96 }, { 100, 180 }, { 56.5f, 143 } }, // 3 | |
{ { 155, 146 }, { 43, 146 }, { 129, 25 }, { 129, 146 }, { 129, 179 } }, // 4 | |
{ { 146, 20 }, { 91, 20 }, { 72, 78 }, { 145, 129 }, { 45, 154 } }, // 5 | |
{ { 110, 20 }, { 110, 20 }, { 46, 126 }, { 153, 126 }, { 53.5f, 100 } }, // 6 | |
{ { 47, 21 }, { 158, 21 }, { 120.67f, 73.34f }, { 83.34f, 126.67f }, { 46, 181 } }, // 7 | |
{ { 101, 96 }, { 101, 19 }, { 101, 96 }, { 101, 179 }, { 101, 96 } }, // 8 | |
{ { 146.5f, 100 }, { 47, 74 }, { 154, 74 }, { 90, 180 }, { 90, 180 } } // 9 | |
}; | |
// The set of the "first" control points of each segment. | |
private final float[][][] mControlPoint1 = { | |
{ { 44.5f, 60 }, { 133, 18 }, { 156, 140 }, { 67, 180 } }, // 0 | |
{ { 77, 20.5f }, { 104.5f, 20.5f }, { 104.5f, 181 }, { 104.5f, 181 } }, // 1 | |
{ { 59, 2 }, { 144.5f, 78 }, { 94, 138 }, { 57, 177 } }, // 2 | |
{ { 63, 27 }, { 156, 18 }, { 158, 96 }, { 54, 180 } }, // 3 | |
{ { 155, 146 }, { 43, 146 }, { 129, 25 }, { 129, 146 } }, // 4 | |
{ { 91, 20 }, { 72, 78 }, { 97, 66 }, { 140, 183 } }, // 5 | |
{ { 110, 20 }, { 71, 79 }, { 52, 208 }, { 146, 66 } }, // 6 | |
{ { 47, 21 }, { 158, 21 }, { 120.67f, 73.34f }, { 83.34f, 126.67f } }, // 7 | |
{ { 44, 95 }, { 154, 19 }, { 44, 96 }, { 154, 179 } }, // 8 | |
{ { 124, 136 }, { 42, 8 }, { 152, 108 }, { 90, 180 } } // 9 | |
}; | |
// The set of the "second" control points of each segment. | |
private final float[][][] mControlPoint2 = { | |
{ { 67, 18 }, { 156, 60 }, { 133, 180 }, { 44.5f, 140 } }, // 0 | |
{ { 104.5f, 20.5f }, { 104.5f, 181 }, { 104.5f, 181 }, { 104.5f, 181 } }, // 1 | |
{ { 143, 4 }, { 130, 98 }, { 74, 155 }, { 147, 177 } }, // 2 | |
{ { 86, 18 }, { 146, 96 }, { 150, 180 }, { 56, 150 } }, // 3 | |
{ { 43, 146 }, { 129, 25 }, { 129, 146 }, { 129, 179 } }, // 4 | |
{ { 91, 20 }, { 72, 78 }, { 145, 85 }, { 68, 198 } }, // 5 | |
{ { 110, 20 }, { 48, 92 }, { 158, 192 }, { 76, 64 } }, // 6 | |
{ { 158, 21 }, { 120.67f, 73.34f }, { 83.34f, 126.67f }, { 46, 181 } }, // 7 | |
{ { 44, 19 }, { 154, 96 }, { 36, 179 }, { 154, 96 } }, // 8 | |
{ { 54, 134 }, { 148, -8 }, { 129, 121 }, { 90, 180 } } // 9 | |
}; | |
public NumberMorphingView(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
setWillNotDraw(false); | |
mInterpolator = new AccelerateDecelerateInterpolator(); | |
// A new paint with the style as stroke. | |
mPaint = new Paint(); | |
mPaint.setAntiAlias(true); | |
mPaint.setColor(Color.BLACK); | |
mPaint.setStrokeWidth(5.0f); | |
mPaint.setStyle(Paint.Style.STROKE); | |
mPath = new Path(); | |
} | |
@Override | |
public void onDraw(Canvas canvas) { | |
int count = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.MATRIX_SAVE_FLAG | |
| Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | |
| Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); | |
super.onDraw(canvas); | |
// Frames 0, 1 is the first pause. | |
// Frames 9, 10 is the last pause. | |
// Constrain current frame to be between 0 and 6. | |
final int currentFrame; | |
if (mFrame < 2) { | |
currentFrame = 0; | |
} else if (mFrame > 8) { | |
currentFrame = 6; | |
} else { | |
currentFrame = mFrame - 2; | |
} | |
// A factor of the difference between current | |
// and next frame based on interpolation. | |
// Only 6 frames are used between the transition. | |
final float factor = mInterpolator.getInterpolation(currentFrame / 6.0f); | |
// Reset the path. | |
mPath.reset(); | |
final float[][] current = mPoints[mCurrent]; | |
final float[][] next = mPoints[mNext]; | |
final float[][] curr1 = mControlPoint1[mCurrent]; | |
final float[][] next1 = mControlPoint1[mNext]; | |
final float[][] curr2 = mControlPoint2[mCurrent]; | |
final float[][] next2 = mControlPoint2[mNext]; | |
// First point. | |
mPath.moveTo(current[0][0] + ((next[0][0] - current[0][0]) * factor), current[0][1] | |
+ ((next[0][1] - current[0][1]) * factor)); | |
// Rest of the points connected as bezier curve. | |
for (int i = 1; i < 5; i++) { | |
mPath.cubicTo(curr1[i - 1][0] + ((next1[i - 1][0] - curr1[i - 1][0]) * factor), | |
curr1[i - 1][1] + ((next1[i - 1][1] - curr1[i - 1][1]) * factor), | |
curr2[i - 1][0] + ((next2[i - 1][0] - curr2[i - 1][0]) * factor), | |
curr2[i - 1][1] + ((next2[i - 1][1] - curr2[i - 1][1]) * factor), current[i][0] | |
+ ((next[i][0] - current[i][0]) * factor), current[i][1] | |
+ ((next[i][1] - current[i][1]) * factor)); | |
} | |
// Draw the path. | |
canvas.drawPath(mPath, mPaint); | |
canvas.restoreToCount(count); | |
// Next frame. | |
mFrame++; | |
// Each number change has 10 frames. Reset. | |
if (mFrame == 10) { | |
// Reset to zarro. | |
mFrame = 0; | |
mCurrent = mNext; | |
mNext++; | |
// Reset to zarro. | |
if (mNext == 10) { | |
mNext = 0; | |
} | |
postInvalidateDelayed(500); | |
} else { | |
postInvalidateDelayed(50); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment