package com.race604.flyrefresh.internal;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.support.v4.view.animation.PathInterpolatorCompat;
import android.view.animation.Interpolator;
import com.race604.flyrefresh.PullHeaderLayout;
/**
* Created by Jing on 15/5/24.
*/
public class MountainSceneDrawable extends Drawable {
private static final int COLOR_BACKGROUND = Color.parseColor("#7ECEC9");
private static final int COLOR_MOUNTAIN_1 = Color.parseColor("#86DAD7");
private static final int COLOR_MOUNTAIN_2 = Color.parseColor("#3C929C");
private static final int COLOR_MOUNTAIN_3 = Color.parseColor("#3E5F73");
private static final int COLOR_TREE_1_BRANCH = Color.parseColor("#1F7177");
private static final int COLOR_TREE_1_BTRUNK = Color.parseColor("#0C3E48");
private static final int COLOR_TREE_2_BRANCH = Color.parseColor("#34888F");
private static final int COLOR_TREE_2_BTRUNK = Color.parseColor("#1B6169");
private static final int COLOR_TREE_3_BRANCH = Color.parseColor("#57B1AE");
private static final int COLOR_TREE_3_BTRUNK = Color.parseColor("#62A4AD");
private static final int WIDTH = 240;
private static final int HEIGHT = 180;
private static final int TREE_WIDTH = 100;
private static final int TREE_HEIGHT = 200;
private Paint mMountPaint = new Paint();
private Paint mTrunkPaint = new Paint();
private Paint mBranchPaint = new Paint();
private Paint mBoarderPaint = new Paint();
private Path mMount1 = new Path();
private Path mMount2 = new Path();
private Path mMount3 = new Path();
private Path mTrunk = new Path();
private Path mBranch = new Path();
private float mScale = 5f;
private float mMoveFactor = 0;
private float mBounceMax = 1;
private float mTreeBendFactor = Float.MAX_VALUE;
private Matrix mTransMatrix = new Matrix();
public MountainSceneDrawable() {
super();
mMountPaint.setAntiAlias(true);
mMountPaint.setStyle(Paint.Style.FILL);
mTrunkPaint.setAntiAlias(true);
mBranchPaint.setAntiAlias(true);
mBoarderPaint.setAntiAlias(true);
mBoarderPaint.setStyle(Paint.Style.STROKE);
mBoarderPaint.setStrokeWidth(2);
mBoarderPaint.setStrokeJoin(Paint.Join.ROUND);
updateMountainPath(mMoveFactor);
updateTreePath(0);
}
private void updateMountainPath(float factor) {
mTransMatrix.reset();
mTransMatrix.setScale(mScale, mScale);
int offset1 = (int) (10 * factor);
mMount1.reset();
mMount1.moveTo(0, 95 + offset1);
mMount1.lineTo(55, 74 + offset1);
mMount1.lineTo(146, 104 + offset1);
mMount1.lineTo(227, 72 + offset1);
mMount1.lineTo(WIDTH, 80 + offset1);
mMount1.lineTo(WIDTH, HEIGHT);
mMount1.lineTo(0, HEIGHT);
mMount1.close();
mMount1.transform(mTransMatrix);
int offset2 = (int) (20 * factor);
mMount2.reset();
mMount2.moveTo(0, 103 + offset2);
mMount2.lineTo(67, 90 + offset2);
mMount2.lineTo(165, 115 + offset2);
mMount2.lineTo(221, 87 + offset2);
mMount2.lineTo(WIDTH, 100 + offset2);
mMount2.lineTo(WIDTH, HEIGHT);
mMount2.lineTo(0, HEIGHT);
mMount2.close();
mMount2.transform(mTransMatrix);
int offset3 = (int) (30 * factor);
mMount3.reset();
mMount3.moveTo(0, 114 + offset3);
mMount3.cubicTo(30, 106 + offset3, 196, 97 + offset3, WIDTH, 104 + offset3);
mMount3.lineTo(WIDTH, HEIGHT);
mMount3.lineTo(0, HEIGHT);
mMount3.close();
mMount3.transform(mTransMatrix);
}
private void updateTreePath(float factor) {
if (factor == mTreeBendFactor) {
return;
}
final Interpolator interpolator = PathInterpolatorCompat.create(0.8f, -0.5f * factor);
final float width = TREE_WIDTH;
final float height = TREE_HEIGHT;
final float maxMove = width * 0.3f * factor;
final float trunkSize = width * 0.05f;
final float branchSize = width * 0.2f;
final float x0 = width / 2;
final float y0 = height;
final int N = 25;
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;
y += dy;
p += dp;
}
mTrunk.reset();
mTrunk.moveTo(x0 - trunkSize, y0);
int max = (int) (N * 0.7f);
int max1 = (int) (max * 0.5f);
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.moveTo(xx[min] - branchSize, yy[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++) {
float f = (i - min) / diff;
mBranch.lineTo(xx[i] - branchSize + f * f * branchSize, yy[i]);
}
for (int i = N; i >= min; i--) {
float f = (i - min) / diff;
mBranch.lineTo(xx[i] + branchSize - f * f * branchSize, yy[i]);
}
}
public void setMoveFactor(int state, float factor) {
float bendFactor;
if (state == PullHeaderLayout.STATE_BOUNCE) {
if (factor < mBounceMax) {
mBounceMax = factor;
}
bendFactor = factor;
} else {
mBounceMax = factor;
bendFactor = Math.max(0, factor);
}
mMoveFactor = Math.max(0, mBounceMax);
updateMountainPath(mMoveFactor);
updateTreePath(bendFactor);
}
private void drawTree(Canvas canvas, float scale, float baseX, float baseY,
int colorTrunk, int colorBranch) {
canvas.save();
final float dx = baseX - TREE_WIDTH * scale / 2;
final float dy = baseY - TREE_HEIGHT * scale;
canvas.translate(dx, dy);
canvas.scale(scale, scale);
mBranchPaint.setColor(colorBranch);
canvas.drawPath(mBranch, mBranchPaint);
mTrunkPaint.setColor(colorTrunk);
canvas.drawPath(mTrunk, mTrunkPaint);
mBoarderPaint.setColor(colorTrunk);
canvas.drawPath(mBranch, mBoarderPaint);
canvas.restore();
}
@Override
public void draw(Canvas canvas) {
canvas.drawColor(COLOR_BACKGROUND);
mMountPaint.setColor(COLOR_MOUNTAIN_1);
canvas.drawPath(mMount1, mMountPaint);
canvas.save();
canvas.scale(-1, 1, getIntrinsicWidth() / 2, 0);
drawTree(canvas, 0.12f * mScale, 180 * mScale, (93 + 20 * mMoveFactor) * mScale,
COLOR_TREE_3_BTRUNK, COLOR_TREE_3_BRANCH);
drawTree(canvas, 0.1f * mScale, 200 * mScale, (96 + 20 * mMoveFactor) * mScale,
COLOR_TREE_3_BTRUNK, COLOR_TREE_3_BRANCH);
canvas.restore();
mMountPaint.setColor(COLOR_MOUNTAIN_2);
canvas.drawPath(mMount2, mMountPaint);
drawTree(canvas, 0.2f * mScale, 160 * mScale, (105 + 30 * mMoveFactor) * mScale,
COLOR_TREE_1_BTRUNK, COLOR_TREE_1_BRANCH);
drawTree(canvas, 0.14f * mScale, 180 * mScale, (105 + 30 * mMoveFactor) * mScale,
COLOR_TREE_2_BTRUNK ,COLOR_TREE_2_BRANCH);
drawTree(canvas, 0.16f * mScale, 140 * mScale, (105 + 30 * mMoveFactor) * mScale,
COLOR_TREE_2_BTRUNK ,COLOR_TREE_2_BRANCH);
mMountPaint.setColor(COLOR_MOUNTAIN_3);
canvas.drawPath(mMount3, mMountPaint);
}
@Override
public void setAlpha(int alpha) {
mMountPaint.setAlpha(alpha);
mTrunkPaint.setAlpha(alpha);
mBranchPaint.setAlpha(alpha);
mBoarderPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
mMountPaint.setColorFilter(cf);
mTrunkPaint.setColorFilter(cf);
mBranchPaint.setColorFilter(cf);
mBoarderPaint.setColorFilter(cf);
}
@Override
public int getOpacity() {
return PixelFormat.OPAQUE;
}
@Override
public int getIntrinsicHeight() {
return (int) (HEIGHT * mScale);
}
@Override
public int getIntrinsicWidth() {
return (int) (WIDTH * mScale);
}
}