serejja
serejja

Reputation: 23851

Canvas animate "closing the book"

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

original image to this enter image description here

I'm able to rotate the canvas like following:

enter image description here and enter image description here

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 Bitmaps 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

Answers (1)

pskink
pskink

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

Related Questions