Search code examples
androidimageanimationmask

Android - Animation with only 2 images and mask


I'm trying to make an animation with only 2 images and using a mask. But I do not know how. I can not use animation-list. I need help to do so. Thank you.

The effect of the animation would look like this:

enter image description here

public void makeMaskImage(ImageView mImageView, int mContent) {

    Bitmap original = BitmapFactory.decodeResource(getResources(), mContent);
    Bitmap mask = BitmapFactory.decodeResource(getResources(),R.drawable.mask);
    Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas mCanvas = new Canvas(result);
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
    mCanvas.drawBitmap(original, 0, 0, null);
    mCanvas.drawBitmap(mask, 0, 0, paint);
    paint.setXfermode(null);
    mImageView.setImageBitmap(result);
    mImageView.setScaleType(ImageView.ScaleType.CENTER);
    mImageView.setBackgroundResource(R.drawable.img_b);
}

animation

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:fillEnabled="true"
android:interpolator="@android:anim/linear_interpolator">

<translate
    android:duration="3000"
    android:fromXDelta="-100%p"
    android:toXDelta="0%p" />

</set>

Solution

  • I modified the class of Nicolas Simon and code works perfectly

    public class RevealView extends ImageView {
    
        private Bitmap secondBitmap;
        private float mAnimationPercentage;
        private Path mPath;
        private Paint mPaint;
    
        public RevealView(Context context) {
            super(context);
            init();
        }
    
        public RevealView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        public RevealView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }
    
        private void init() {
            setPercentage(0);
    
            mPaint = new Paint();
            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));
            mPath = new Path();
        }
    
        public void setPercentage(int p) {
            if(p > 100) {
                p = 100;
            }
            mAnimationPercentage = p / 100f;
            invalidate();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            Bitmap mRegularBitmap = ((BitmapDrawable) getDrawable()).getBitmap();
            if (mRegularBitmap != null && secondBitmap != null) {
                //First draw your regular image
                canvas.drawBitmap(mRegularBitmap, 0, 0, null);
    
                //Then clip the canvas depending on the animation percentage, using a Path
                mPath.reset();
                mPath.moveTo((float) canvas.getWidth() * mAnimationPercentage, 0.0f);
                mPath.lineTo((float) canvas.getWidth() * mAnimationPercentage, canvas.getHeight());
                mPath.lineTo(canvas.getWidth(), canvas.getHeight());
                mPath.lineTo(canvas.getWidth(), 0.0f);
                mPath.close();
    
                canvas.drawPath(mPath, mPaint);
                canvas.clipPath(mPath);
    
                //Then draw the gray bitmap on top
                canvas.drawBitmap(secondBitmap, 0.0f, 0.0f, null);
            }
        }
    
        public void setSecondBitmap(Bitmap secondBitmap) {
            this.secondBitmap = secondBitmap;
        }
    }
    

    MainActivity

    @Override
    public void onResume() {
        super.onResume();
    
        revealView.setSecondBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.img_1));
    
        percentage = 0;
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (percentage <= 100) {
                            revealView.setPercentage(percentage);
                            percentage++;
                        } else {
                            cancel();
                        }
                    }
                });
            }
        }, 0, 120);
    }
    

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <com.example.animation.RevealView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/img_2" />
    
    </RelativeLayout>