package com.tencent.livebackground.animation;
import java.util.LinkedList;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Bundle;
import android.os.SystemClock;
import com.tencent.livebackground.util.Recyclable;
import com.tencent.livebackground.util.SpringDynamics;
public class ParticleRenderer implements Renderer, Recyclable {
private static final LinkedList<ParticleRenderer> mRecycleStack = new LinkedList<ParticleRenderer>();
private RectF mCurrentRect;
private final SpringDynamics mDynamicsLeft = new SpringDynamics();
private final SpringDynamics mDynamicsTop = new SpringDynamics();
private SpringDynamics mDynamicsZ;
private SpringDynamics mAlphaDynamics;
private Paint mPaint;
private ParticleRenderer() {
mPaint = new Paint();
mCurrentRect = new RectF();
mDynamicsZ = new SpringDynamics();
mDynamicsZ.setSpring(50F, 1.0F);
mAlphaDynamics = new SpringDynamics();
mAlphaDynamics.setSpring(50F, 1.0F);
}
public void setScale(float scale) {
mDynamicsZ.setState(scale, 0.0F, 0);
}
public void setAlpha(float alpha) {
mAlphaDynamics.setState(alpha, 0.0F, 0);
}
private void drawView(Bitmap bitmap, Canvas canvas, RectF rectf,
float zFactor) {
if (bitmap != null && !bitmap.isRecycled()) {
Paint paint = mPaint;
canvas.save();
canvas.translate(rectf.left, rectf.top);
float zPosition = mDynamicsZ.getPosition();
canvas.scale(zPosition, zPosition);
paint.setAlpha((int)mAlphaDynamics.getPosition());
canvas.drawBitmap(bitmap, 0, 0, paint);
canvas.restore();
}
}
public static ParticleRenderer obtain() {
if (!mRecycleStack.isEmpty())
return (ParticleRenderer) mRecycleStack.removeLast();
else
return new ParticleRenderer();
}
private float update(Rect rect, long timeMillis) {
mDynamicsZ.update(timeMillis);
mAlphaDynamics.update(timeMillis);
float zPosition = mDynamicsZ.getPosition();
if (zPosition < 0.0F)
zPosition = -zPosition;
mDynamicsLeft.update(timeMillis);
mDynamicsTop.update(timeMillis);
return zPosition;
}
public boolean draw(Bitmap bitmap, Canvas canvas, Rect rect, long timeMillis) {
float f = update(rect, timeMillis);
int offsetX = (int)mDynamicsLeft.getPosition();
int offsetY = (int)mDynamicsTop.getPosition();
if(Math.abs(offsetX) > 1000 || Math.abs(offsetY) > 1000) {
offsetX = 1000;
offsetY = 1000;
}
mCurrentRect.offsetTo(mDynamicsLeft.getPosition(),
mDynamicsTop.getPosition());
drawView(bitmap, canvas, mCurrentRect, f);
return !mDynamicsLeft.isAtRest(1.0F, 1F)
|| !mDynamicsTop.isAtRest(1.0F, 1F);
}
public void getCurrentRect(Rect rect) {
if (rect != null) {
rect.left = (int) mCurrentRect.left;
rect.right = (int) mCurrentRect.right;
rect.top = (int) mCurrentRect.top;
rect.bottom = (int) mCurrentRect.bottom;
}
}
public void offset(int dx, int dy, long timeMillis) {
mCurrentRect.offset(dx, dy);
mDynamicsLeft.setState(mDynamicsLeft.getPosition() + (float) dx,
mDynamicsLeft.getVelocity(), timeMillis);
mDynamicsTop.setState(mDynamicsTop.getPosition() + (float) dy,
mDynamicsTop.getVelocity(), timeMillis);
}
public void recycle() {
mRecycleStack.addLast(this);
}
public void sendCommand(String command, int x, int y, Bundle extras) {
if (command.equals("stop")) {
mDynamicsZ.setMaxPosition(0.0F);
mDynamicsZ.setMinPosition(0.0F);
mDynamicsZ.setSpring(600F, 0.85F);
mDynamicsZ.setState(mDynamicsZ.getPosition(), 60F,
SystemClock.uptimeMillis());
mDynamicsLeft.setSpring(400F, 0.9F);
mDynamicsTop.setSpring(400F, 0.9F);
}
}
public void start(Rect rect, int targetX, int targetY, float toScale, float toAlpha, long timeMillis) {
if(Math.abs(targetX) > 1000 || Math.abs(targetY) > 1000) {
targetX = 1000;
targetY = 1000;
}
mCurrentRect.set(rect);
mDynamicsLeft.setState(rect.left, 0.0F, timeMillis);
mDynamicsLeft.setMaxPosition(targetX);
mDynamicsLeft.setMinPosition(targetX);
mDynamicsTop.setState(rect.top, 0.0F, timeMillis);
mDynamicsTop.setMaxPosition(targetY);
mDynamicsTop.setMinPosition(targetY);
mDynamicsLeft.setSpring(50F, 1.2F);
mDynamicsTop.setSpring(50F, 1.2F);
mDynamicsZ.setState(mDynamicsZ.getPosition(), 0.0F, timeMillis);
mDynamicsZ.setMaxPosition(toScale);
mDynamicsZ.setMinPosition(toScale);
mDynamicsZ.setSpring(10F, 1.0F);
mAlphaDynamics.setState(mAlphaDynamics.getPosition(), 0.0F, timeMillis);
mAlphaDynamics.setMaxPosition(toAlpha);
mAlphaDynamics.setMinPosition(toAlpha);
mAlphaDynamics.setSpring(50F, 1.0F);
}
}