package io.virtualapp.widgets;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
public class TwoGearsView extends BaseView {
ValueAnimator valueAnimator = null;
float mAnimatedValue = 0f;
float hypotenuse = 0f;
float smallRingCenterX = 0f;
float smallRingCenterY = 0f;
float bigRingCenterX = 0f;
float bigRingCenterY = 0f;
private float mWidth = 0f;
private Paint mPaint, mPaintAxle;
private Paint mPaintRing;
private float mPadding = 0f;
private float mWheelLength;
private int mWheelSmallSpace = 10;
private int mWheelBigSpace = 8;
public TwoGearsView(Context context) {
super(context);
}
public TwoGearsView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TwoGearsView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (getMeasuredWidth() > getHeight())
mWidth = getMeasuredHeight();
else
mWidth = getMeasuredWidth();
}
private void drawSmallRing(Canvas canvas) {
hypotenuse = (float) (mWidth * Math.sqrt(2));
smallRingCenterX = (float) ((hypotenuse / 6.f) * Math.cos(45 * Math.PI / 180f));
smallRingCenterY = (float) ((hypotenuse / 6.f) * Math.sin(45 * Math.PI / 180f));
mPaintRing.setStrokeWidth(dip2px(1.0f));
canvas.drawCircle(mPadding + smallRingCenterX, smallRingCenterY + mPadding, smallRingCenterX, mPaintRing);
mPaintRing.setStrokeWidth(dip2px(1.5f));
canvas.drawCircle(mPadding + smallRingCenterX, smallRingCenterY + mPadding, smallRingCenterX / 2, mPaintRing);
}
private void drawSmallGear(Canvas canvas) {
mPaint.setStrokeWidth(dip2px(1));
for (int i = 0; i < 360; i = i + mWheelSmallSpace) {
int angle = (int) (mAnimatedValue * mWheelSmallSpace + i);
float x3 = (float) ((smallRingCenterX) * Math.cos(angle * Math.PI / 180f));
float y3 = (float) ((smallRingCenterY) * Math.sin(angle * Math.PI / 180f));
float x4 = (float) ((smallRingCenterX + mWheelLength) * Math.cos(angle * Math.PI / 180f));
float y4 = (float) ((smallRingCenterY + mWheelLength) * Math.sin(angle * Math.PI / 180f));
canvas.drawLine(mPadding + smallRingCenterX - x4,
smallRingCenterY + mPadding - y4,
smallRingCenterX + mPadding - x3,
smallRingCenterY + mPadding - y3,
mPaint);
}
}
private void drawBigGear(Canvas canvas) {
bigRingCenterX = (float) ((hypotenuse / 2.f) * Math.cos(45 * Math.PI / 180f));
bigRingCenterY = (float) ((hypotenuse / 2.f) * Math.sin(45 * Math.PI / 180f));
float strokeWidth = dip2px(1.5f) / 4;
mPaint.setStrokeWidth(dip2px(1.5f));
for (int i = 0; i < 360; i = i + mWheelBigSpace) {
int angle = (int) (360 - (mAnimatedValue * mWheelBigSpace + i));
float x3 = (float) ((bigRingCenterX - smallRingCenterX) * Math.cos(angle * Math.PI / 180f));
float y3 = (float) ((bigRingCenterY - smallRingCenterY) * Math.sin(angle * Math.PI / 180f));
float x4 = (float) ((bigRingCenterX - smallRingCenterX + mWheelLength) * Math.cos(angle * Math.PI / 180f));
float y4 = (float) ((bigRingCenterY - smallRingCenterY + mWheelLength) * Math.sin(angle * Math.PI / 180f));
canvas.drawLine(bigRingCenterX + mPadding - x4 + mWheelLength * 2 + strokeWidth,
bigRingCenterY + mPadding - y4 + mWheelLength * 2 + strokeWidth,
bigRingCenterX + mPadding - x3 + mWheelLength * 2 + strokeWidth,
bigRingCenterY + mPadding - y3 + mWheelLength * 2 + strokeWidth,
mPaint);
}
}
private void drawBigRing(Canvas canvas) {
float strokeWidth = dip2px(1.5f) / 4;
mPaintRing.setStrokeWidth(dip2px(1.5f));
canvas.drawCircle(bigRingCenterX + mPadding + mWheelLength * 2 + strokeWidth,
bigRingCenterY + mPadding + mWheelLength * 2 + strokeWidth,
bigRingCenterX - smallRingCenterX - strokeWidth, mPaintRing);
mPaintRing.setStrokeWidth(dip2px(1.5f));
canvas.drawCircle(bigRingCenterX + mPadding + mWheelLength * 2 + strokeWidth,
bigRingCenterY + mPadding + mWheelLength * 2 + strokeWidth,
(bigRingCenterX - smallRingCenterX) / 2 - strokeWidth, mPaintRing);
}
private void drawAxle(Canvas canvas) {
for (int i = 0; i < 3; i++) {
float x3 = (float) ((smallRingCenterX) * Math.cos(i * (360 / 3) * Math.PI / 180f));
float y3 = (float) ((smallRingCenterY) * Math.sin(i * (360 / 3) * Math.PI / 180f));
canvas.drawLine(mPadding + smallRingCenterX,
mPadding + smallRingCenterY,
mPadding + smallRingCenterX - x3,
mPadding + smallRingCenterY - y3, mPaintAxle);
}
for (int i = 0; i < 3; i++) {
float x3 = (float) ((bigRingCenterX - smallRingCenterX) * Math.cos(i * (360 / 3) * Math.PI / 180f));
float y3 = (float) ((bigRingCenterY - smallRingCenterY) * Math.sin(i * (360 / 3) * Math.PI / 180f));
canvas.drawLine(bigRingCenterX + mPadding + mWheelLength * 2,
bigRingCenterY + mPadding + mWheelLength * 2,
bigRingCenterX + mPadding + mWheelLength * 2 - x3,
bigRingCenterY + mPadding + mWheelLength * 2 - y3,
mPaintAxle);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPadding = dip2px(5);
canvas.save();
canvas.rotate(180, mWidth / 2, mWidth / 2);
drawSmallRing(canvas);
drawSmallGear(canvas);
drawBigGear(canvas);
drawBigRing(canvas);
drawAxle(canvas);
canvas.restore();
}
private void initPaint() {
mPaintRing = new Paint();
mPaintRing.setAntiAlias(true);
mPaintRing.setStyle(Paint.Style.STROKE);
mPaintRing.setColor(Color.WHITE);
mPaintRing.setStrokeWidth(dip2px(1.5f));
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.WHITE);
mPaint.setStrokeWidth(dip2px(1));
mPaintAxle = new Paint();
mPaintAxle.setAntiAlias(true);
mPaintAxle.setStyle(Paint.Style.FILL);
mPaintAxle.setColor(Color.WHITE);
mPaintAxle.setStrokeWidth(dip2px(1.5f));
mWheelLength = dip2px(2f);
}
public void setViewColor(int color) {
mPaint.setColor(color);
mPaintAxle.setColor(color);
mPaintRing.setColor(color);
postInvalidate();
}
@Override
protected void InitPaint() {
initPaint();
}
@Override
protected void OnAnimationUpdate(ValueAnimator valueAnimator) {
mAnimatedValue = (float) valueAnimator.getAnimatedValue();
postInvalidate();
}
@Override
protected void OnAnimationRepeat(Animator animation) {
}
@Override
protected int OnStopAnim() {
postInvalidate();
return 1;
}
@Override
protected int SetAnimRepeatMode() {
return ValueAnimator.RESTART;
}
@Override
protected void AnimIsRunning() {
}
@Override
protected int SetAnimRepeatCount() {
return ValueAnimator.INFINITE;
}
private int dip2px(float dpValue) {
final float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}