Reputation: 23851
First of all I never used canvas transformations before. But here is that I have to do:
say I have a canvas that holds an image. I need to transform it like this
to this
I'm able to rotate the canvas like following:
and
Here is the code I'm using for the left one:
public void transformCanvas(Canvas canvas, float percentOpen) {
Camera camera = new Camera();
canvas.translate(0, canvas.getHeight()/2);
camera.translate(0, 0, Math.abs(90 * percentOpen - 90));
camera.rotateY(Math.abs(90 * percentOpen - 90));
Matrix matrix = new Matrix();
camera.getMatrix(matrix);
canvas.concat(matrix);
canvas.translate(0, -canvas.getHeight()/2);
}
percentOpen
holds the value from 0
to 1
so that when percentOpen
decreases the canvas rotates till it becomes invisible and when percentOpen
increases the canvas returns to its original state.
I'm able to animate both left and right variants, I just cannot figure out how should I divide the canvas into two parts (or even should I divide it somehow?) to animate the left and right parts independently.
I tried taking the bitmap of the view, divide it into two Bitmap
s and rotate them independently but this was very slow.
I'd be very glad for any help.
How can I rotate the left and right sides independently?
Upvotes: 1
Views: 365
Reputation: 24720
try this custom Animation:
class V extends View implements OnClickListener {
private A animation;
private Paint paint0;
private Paint paint1;
private RectF rect;
private Bitmap bitmap;
public V(Context context) {
super(context);
paint0 = new Paint();
paint0.setColor(0xffaa0000);
paint1 = new Paint();
paint1.setColor(0xffffffff);
rect = new RectF();
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
setOnClickListener(this);
}
@Override
public void onClick(View v) {
Log.d(TAG, "onClick ");
animation = new A(getWidth(), getHeight());
startAnimation(animation);
}
@Override
protected void onDraw(Canvas canvas) {
int w = getWidth();
int h = getHeight();
if (animation != null && animation.hasStarted() && !animation.hasEnded()) {
canvas.save();
canvas.clipRect(0, 0, w / 2, h, Op.REPLACE);
canvas.concat(animation.leftMatrix);
drawStuff(canvas, w, h);
canvas.restore();
canvas.save();
canvas.clipRect(w / 2, 0, w, h, Op.REPLACE);
canvas.concat(animation.rightMatrix);
drawStuff(canvas, w, h);
canvas.restore();
} else {
drawStuff(canvas, w, h);
}
}
public void drawStuff(Canvas canvas, int w, int h) {
int s = Math.min(w, h);
rect.set(0, 0, s, s);
rect.offset((w - s) / 2, (h - s) / 2);
canvas.drawRect(rect, paint0);
rect.left += 64;
rect.top += 64;
canvas.drawOval(rect, paint1);
canvas.drawBitmap(bitmap, rect.left, rect.top, null);
}
class A extends Animation {
private Camera camera;
private int w2;
private int h2;
public Matrix leftMatrix;
public Matrix rightMatrix;
public A(int w, int h) {
camera = new Camera();
leftMatrix = new Matrix();
rightMatrix = new Matrix();
w2 = w / 2;
h2 = h / 2;
setDuration(2000);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
camera.save();
float angle = 80 * interpolatedTime;
camera.rotateY(angle);
camera.getMatrix(leftMatrix);
leftMatrix.preTranslate(-w2, -h2);
leftMatrix.postTranslate(w2, h2);
camera.rotateY(-2 * angle);
camera.getMatrix(rightMatrix);
rightMatrix.preTranslate(-w2, -h2);
rightMatrix.postTranslate(w2, h2);
camera.restore();
}
}
}
Upvotes: 2