Effect display
Implementation steps
1. Draw a circle mask
Here we use the mixed mode to realize the deduction of the circle part. Here we use PorterDuff.Mode.CLEAR
/** * Draw circle mask * @param canvas */ private void drawCircleMask(Canvas canvas) { canvas.save(); //Target map Dst canvas.drawRect(new Rect(0,0,getWidth(),getHeight()), mPaint); //Set blend mode mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); //Source image Src, lower right corner of overlapping area canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 3, mPaint); //Clear blend mode mPaint.setXfermode(null); canvas.restore(); }
The effect is as follows
2. Draw two animated circles
The two pictures we draw are as follows
What we need to do is to scale the Bitmap to the same size as the circle of the previous mask effect by calculation, because the two pictures we use here are the same size, so we only need to calculate the scaling ratio of the inner circle picture and the mask circle, because the radius we set for the mask circle is: control width / 3
Therefore, the width and height of the scaled circle Bitmap should be the total length of the middle red line plus the blue parts on both sides as shown in the figure below
The middle red line is: control width / 3 , The blue line can be measured by PhotoShop and other tools, and then calculated according to the proportion with the red line. The code is as follows, where mInnerCircleBitmap is the inner circle and mOutCircleBitmap is the outer circle
/** * Draw a picture of the circle outside the circle */ private void drawBitmapCircle(Canvas canvas) { if(mInnerCircleBitmap == null){ int dstWidthAndHeight = (int) (getWidth() / 1.5f + getWidth() / 1.5f / 4); mInnerCircleBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_checkface_innercircle); mInnerCircleBitmap = Bitmap.createScaledBitmap(mInnerCircleBitmap,dstWidthAndHeight,dstWidthAndHeight,true); } if(mOutCircleBitmap == null){ int dstWidthAndHeight = (int) (getWidth() / 1.5f + getWidth() / 1.5f / 4); mOutCircleBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_checkface_outcircle); mOutCircleBitmap = Bitmap.createScaledBitmap(mOutCircleBitmap,dstWidthAndHeight,dstWidthAndHeight,true); } int left = (getWidth() - mInnerCircleBitmap.getWidth()) / 2; int top = (int) (getWidth() / 2 - getWidth() / 3 - getWidth() / 1.5f / 8); canvas.drawBitmap(mInnerCircleBitmap,left,top,mPaint); canvas.drawBitmap(mOutCircleBitmap,left,top,mPaint); }
The effect is as follows
3. Realize the rotation animation effect
Next, we can realize the rotation effect of the circle through ValueAnimator. From the effect at the beginning of the article, we can see that the rotation directions of the two circles are different. Therefore, we should also pay attention to the clockwise rotation and the counterclockwise rotation logically. The code is as follows
private float mDegress = 0;//Rotation angle private void init() { //Define animation valueAnimator = ValueAnimator.ofFloat(0f, 360f); valueAnimator.setRepeatCount(ValueAnimator.INFINITE); valueAnimator.setRepeatMode(ValueAnimator.RESTART); valueAnimator.setInterpolator(new LinearInterpolator()); valueAnimator.setDuration(6000); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mDegress = (float) animation.getAnimatedValue(); postInvalidate(); } }); valueAnimator.start(); } /** * Draw a picture of the circle outside the circle */ private void drawBitmapCircle(Canvas canvas) { if(mInnerCircleBitmap == null){ int dstWidthAndHeight = (int) (getWidth() / 1.5f + getWidth() / 1.5f / 4); mInnerCircleBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_checkface_innercircle); mInnerCircleBitmap = Bitmap.createScaledBitmap(mInnerCircleBitmap,dstWidthAndHeight,dstWidthAndHeight,true); } if(mOutCircleBitmap == null){ int dstWidthAndHeight = (int) (getWidth() / 1.5f + getWidth() / 1.5f / 4); mOutCircleBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_checkface_outcircle); mOutCircleBitmap = Bitmap.createScaledBitmap(mOutCircleBitmap,dstWidthAndHeight,dstWidthAndHeight,true); } int left = (getWidth() - mInnerCircleBitmap.getWidth()) / 2; int top = (int) (getWidth() / 2 - getWidth() / 3 - getWidth() / 1.5f / 8); //Clockwise rotation canvas.save(); canvas.rotate(mDegress,getWidth() / 2, getWidth() / 2); canvas.drawBitmap(mInnerCircleBitmap,left,top,mPaint); canvas.restore(); //Counterclockwise rotation canvas.save(); canvas.rotate(-mDegress,getWidth() / 2, getWidth() / 2); canvas.drawBitmap(mOutCircleBitmap,left,top,mPaint); canvas.restore(); }
The effect is as follows
4. Add prompt text
Drawing text is relatively simple. It is mainly used to prompt users for operations. The code is as follows
canvas.drawText("Please move your face into the circle",getWidth() / 2, (float) (getWidth() * 1.2),mTextPaint);
The final effect is as follows
Case source code
The source code in the above implementation steps is split. The detailed and complete code can be obtained at the following address https://gitee.com/itfitness/f...
Original link: https://www.jianshu.com/p/938...
end of document
Your favorite collection is my greatest encouragement!
Welcome to follow me, share Android dry goods and exchange Android technology.
If you have any opinions on the article or any technical problems, please leave a message in the comment area for discussion!