package com.race604.flyrefresh.internal;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.support.v4.view.animation.PathInterpolatorCompat;
import android.util.FloatMath;
import android.view.animation.Interpolator;
/**
* Created by jing on 15-5-22.
*/
public class TreeDrawable extends Drawable {
private static final int DEFAULT_WIDTH = 100;
private static final int DEFAULT_HEIGHT = 200;
private float mSizeFactor = 1;
private float mBendScale = 0f;
private Paint mTrunkPaint = new Paint();
private Paint mBranchPaint = new Paint();
private Path mTrunk = new Path();
private Path mBranch = new Path();
private Path mBaseLine = new Path();
private Paint mBaseLinePaint = new Paint();
public TreeDrawable() {
super();
mTrunkPaint.setAntiAlias(true);
mTrunkPaint.setStrokeWidth(0.1f);
mTrunkPaint.setColor(Color.DKGRAY);
mBranchPaint.setAntiAlias(true);
mBranchPaint.setColor(Color.GREEN);
mBaseLinePaint.setAntiAlias(true);
mBaseLinePaint.setColor(Color.RED);
mBaseLinePaint.setStrokeWidth(0.5f);
mBaseLinePaint.setStyle(Paint.Style.STROKE);
updateTree();
}
public void setBendScale(float scale) {
mBendScale = scale;
updateTree();
}
public void updateTree() {
final Interpolator interpolator = PathInterpolatorCompat.create(0.8f, -0.6f * mBendScale);
final float width = DEFAULT_WIDTH * mSizeFactor;
final float height = DEFAULT_HEIGHT * mSizeFactor;
final float maxMove = width * 0.45f * mBendScale;
final float trunkSize = width * 0.05f;
final float branchSize = width * 0.2f;
final float x0 = width / 2;
final float y0 = height;
mBaseLine.reset();
mBaseLine.moveTo(x0, y0);
final int N = 50;
final float dp = 1f / N;
final float dy = -dp * height;
float y = y0;
float p = 0;
float[] xx = new float[N + 1];
float[] yy = new float[N + 1];
for (int i = 0; i <= N; i++) {
xx[i] = interpolator.getInterpolation(p) * maxMove + x0;
yy[i] = y;
mBaseLine.lineTo(xx[i], yy[i]);
y += dy;
p += dp;
}
mTrunk.reset();
mTrunk.moveTo(x0 - trunkSize, y0);
int max = (int) (N * 0.6f);
int max1 = (int) (max * 0.6f);
float diff = max - max1;
for (int i = 0; i < max; i++) {
if (i < max1) {
mTrunk.lineTo(xx[i] - trunkSize, yy[i]);
} else {
mTrunk.lineTo(xx[i] - trunkSize * (max - i) / diff, yy[i]);
}
}
for (int i = max - 1; i >= 0; i--) {
if (i < max1) {
mTrunk.lineTo(xx[i] + trunkSize, yy[i]);
} else {
mTrunk.lineTo(xx[i] + trunkSize * (max - i) / diff, yy[i]);
}
}
mTrunk.close();
mBranch.reset();
int min = (int) (N * 0.4f);
diff = N - min;
mBranch.addArc(new RectF(xx[min] - branchSize, yy[min] - branchSize, xx[min] + branchSize, yy[min] + branchSize), 0f, 180f);
for (int i = min; i <= N; i++) {
mBranch.lineTo(xx[i] + branchSize - ((i - min) / diff) * branchSize, yy[i]);
}
for (int i = N; i >= min; i--) {
mBranch.lineTo(xx[i] - branchSize + ((i - min) / diff) * branchSize, yy[i]);
}
mBranch.close();
}
@Override
public int getIntrinsicWidth() {
return (int) (DEFAULT_WIDTH * mSizeFactor);
}
@Override
public int getIntrinsicHeight() {
return (int) (DEFAULT_HEIGHT * mSizeFactor);
}
@Override
public void draw(Canvas canvas) {
canvas.drawPath(mBranch, mBranchPaint);
canvas.drawPath(mTrunk, mTrunkPaint);
canvas.drawPath(mBaseLine, mBaseLinePaint);
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter cf) {
}
@Override
public int getOpacity() {
return 0;
}
private static float getQuadPoint(float x0, float y0, float x1, float y1,
float x2, float y2, float x) {
float t;
float a = (x0 - 2 * x1 + x2);
float b = 2 * (x1 - x0);
float c = x1 - x;
if (a < 1e-10) {
t = (x1 - x) / (2 * (x1 - x0));
} else {
t = (float) ((Math.sqrt(b * b - 4 * a * c) + b) / (2 * a));
}
float t1 = 1 - t;
return t1 * t1 * y0 + 2 * t * t1 * y1 + t * t * y2;
}
}