Experience a wave of Android custom view s and realize super cute dynamic bombs!!

Posted by Sarahlmorrow on Sun, 12 Dec 2021 03:54:49 +0100

Old rules, let's take a look at the renderings first!

Let's look at the implementation effect of android.

Let's start to analyze the animation like the super cute dynamic weather little sun realized by the custom view! (if you haven't seen the weather sun, you can go to see the weather sun first. Some of the routines talked about by the weather sun will no longer be talked about. At the same time, you need to master path, camera, Bezier curve, etc., otherwise some codes may cause discomfort).

Let's draw the static view first, and then realize the animation, let's go.

1. Floor

You can see that the floor is actually a straight line. Then two gaps in the middle. How can this be achieved? Little friends who see the little sun may say that it's very simple. Just draw a straight line and cover two white areas. Indeed, this can be achieved, but careful observation shows that the notch below is realized by two semicircles and rectangles, which is a little troublesome and inconvenient to move the notch position. What's the easy way? Yes, that is, use Path to draw a straight line, and then set the round pen head, and then set the dashpatheffect (to achieve the effect of dotted line, one section drawing and one section not drawing, and the length of each section can be controlled freely). The code is as follows:

float[] groundEffectFloat=new float[]  {        bombLineWidth/4,bombLineWidth/2+bombLineWidth,bombLineWidth*2,bombLineWidth/3*2+bombLineWidth,getMeasuredWidth(),0};//Set the length of draw and no draw
        groundDashPathEffect=new DashPathEffect(groundEffectFloat,0);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(bombLineColor);
        mPaint.setPathEffect(groundDashPathEffect);//Set dashed line effect
        mPath.reset();
        mPath.moveTo(bombLineWidth/2,getMeasuredHeight()-bombLineWidth/2);
        mPath.lineTo(getMeasuredWidth()-bombLineWidth/2,getMeasuredHeight()-  
        bombLineWidth/2);
        canvas.drawPath(mPath,mPaint);

2. Body frame

Take a closer look! Smart, you must say it's too simple. It's just a circle, and then use DashPathEffect to realize the gap!! Well, yes, that's it. Direct release code:

mPaint.setPathEffect(bodyDashPathEffect);
        mPaint.setColor(bombLineColor);
        mPaint.setStyle(Paint.Style.STROKE);
        mPath.reset();
        mPath.addCircle(bombCenterX,bombCenterY,bodyRadius,   
        Path.Direction.CW);
        canvas.drawPath(mPath,mPaint);
        canvas.restore();

Simple! It can't be simpler. Let's look at the body

3. Body

You can find that the body is actually a circle, and then add the highlight in the upper left corner. So how does the highlight work?

Highlight three points. It's very simple. Draw an arc with Path, and then use the DashPathEffect effect effect. It's perfect.

What about another highlight? Look at the picture.

You can see that it is composed of an arc and a path, and then cut to keep it in the circle. The formation of path is to take two points of radian, and then draw it with Bezier curve. The control point is located in the midpoint of radian (red point in the figure below).

The code is as follows: (part of the code, highlight in the upper left corner, please check the source code for others)

       //Light edge in upper left corner
        mPaint.setPathEffect(null);
        mRectF.set(bombCenterX-bodyRadius+bombLineWidth/2,bombCenterY-bodyRadius+bombLineWidth/2
        ,bombCenterX+bodyRadius-bombLineWidth/2,getMeasuredHeight()-bombLineWidth-bombLineWidth/2);
        canvas.drawArc(mRectF,160,100,false,mPaint);        //Splicing light edge
        mPath.reset();
        mPath.addCircle(bombCenterX,bombCenterY,bodyRadius-bombLineWidth/2, Path.Direction.CCW);
        canvas.save();
        canvas.clipPath(mPath);//Within clipping circle

        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(lightColor);
        canvas.drawPath(mBodyLightPath,mPaint);
        canvas.restore();

4. Face

As you can see, well, you're a little complicated. In fact, it's OK. This is because the Z-axis rotation is used. It looks a little complicated. Let's move to the middle.

It seems simple, eyes and dimples are simple, 4 circles!! Mouth, this... This seems a little disgusting. Actually, it's not. Look at the picture.

In fact, it can be realized by adding a circle and a path map. The red dot represents the control point. Hollow points represent nodes. Careful friends may find it wrong. The underside of the tongue is not all red. It is separated from the mouth. Here you just need to scale down your mouth and make an Xfermode with your mouth. Part code:

//Draw the circle of the tongue and the zoom of the mouth. mpath is the path of the mouth
        int save=canvas.saveLayer(0,0,getMeasuredWidth(),getMeasuredHeight(),null,Canvas.ALL_SAVE_FLAG);
        canvas.drawPath(mPath,mPaint);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        mPaint.setColor(Color.parseColor("#f34671"));
        canvas.drawCircle(bombCenterX,mouthY+(mouthMaxY-mouthY)/8+bodyRadius/(5-1.4f*mouthOffsetPercent),bodyRadius/5,mPaint);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        canvas.scale(0.8f,0.8f,bombCenterX,(mouthMaxY+mouthY)/2);
        canvas.drawPath(mPath,mPaint);
        canvas.restoreToCount(save);
        mPaint.setXfermode(null);

5. Shadow on the face (I don't know what it's called, temporarily called shadow mask)

Look, some good friends said, you won't let me draw with Bezier curve again! This is hard to find!! Calm down, the implementation is as follows:

It is so simple that the two circles take the part where the red circle does not intersect.

//The intersection of two circles produces a shadow
        int save=canvas.saveLayer(0,0,getMeasuredWidth(),getMeasuredHeight(),null,Canvas.ALL_SAVE_FLAG);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(bombShadowColor);
        canvas.drawCircle(bombCenterX,bombCenterY,bodyRadius-bombLineWidth/2,mPaint);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
        canvas.translate(-bodyRadius/5,-bodyRadius/5);
        mPaint.setColor(bombColor);
        canvas.drawCircle(bombCenterX,bombCenterY,bodyRadius-bombLineWidth/2,mPaint);
        canvas.restoreToCount(save);
        mPaint.setXfermode(null);

6. Head

Little buddy, say it again. This is not easy to draw, not easy to draw!! Calm down, calm down. This is actually simpler. Just put your head on the back layer of your body. Look at the picture:

code:

It's too simple. I don't want to post it. Pretend I'm code

7. Lead

This lead is actually a line curve, and Bessel curve continues to play (please face the wall if you don't explain or don't understand).

8. Explosion effect

Simple is not very simple anymore. Draw 4 circles with radius from large to small, and then dig out the middle. so easy!!

int save = canvas.saveLayer(0,0,getMeasuredWidth(),getMeasuredHeight(),null,Canvas.ALL_SAVE_FLAG);        float distance = maxBlastCircleRadius/12;        //Draw a circle
        mPaint.setColor(lightColor);
        canvas.drawCircle(bombCenterX,circleY, currentBlastCircleRadius,mPaint);
        mPaint.setColor(bombColor);
        canvas.drawCircle(bombCenterX,circleY, currentBlastCircleRadius -distance,mPaint);
        mPaint.setColor(bombLineColor);
        canvas.drawCircle(bombCenterX,circleY, currentBlastCircleRadius -distance*2,mPaint);
        mPaint.setColor(lightColor);
        canvas.drawCircle(bombCenterX,circleY, currentBlastCircleRadius -distance*3,mPaint);        //use up
        if (blastCircleRadiusPercent >0.65) {
            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
            canvas.drawCircle(bombCenterX, circleY, currentBlastCircleRadius - maxBlastCircleRadius * 0.65f, mPaint);
            mPaint.setXfermode(null);
        }
        canvas.restoreToCount(save);

Here, we have completed half of the display of the small bomb. Now it's time for animation! Play again

9. Face moving animation

You can see the left and right movement. At the time of movement, we only need to add an offset at the time of drawing the face. Then, in the process of movement, we will find that the face will rotate around the center of the bomb body. So the code is as follows

canvas.save();
        mCamera.save();
        mCamera.rotate(bombTBRotate,0,-bombLRRotate/3);
        mMatrix.reset();
        mCamera.getMatrix(mMatrix);
        mCamera.restore();
        mMatrix.preTranslate(-bombCenterX,-(bombCenterY));
        mMatrix.postTranslate(bombCenterX,bombCenterY);
        mMatrix.postTranslate(faceLROffset,faceTBOffset);
        canvas.setMatrix(mMatrix);

Use camera to rotate the z axis, then translate left and right, and then use valueanimator animation to set the variable offset, done! During the movement, you can find the effect of squinting your eyes. This is very simple. You can use ellipses to realize the eyes. Keep the width unchanged and change the height.

10. The body head lead rotates left and right

This is even simpler. You only need to use camera rotation transformation to obtain martix before painting, and then transform canvas.

11. Face moving up and down

First, like moving the face left and right, use matrix Translate to move up and down. The same goes for eye changes. The back eye magnification effect is to enlarge the radius of the circle when it becomes a round eye.
The transformation of the mouth is relatively complex! Look at the picture, I don't know if I can speak clearly!!!!

This is the picture of the mouth just now!!! Mouth animation has two parts!! (the following statements may cause discomfort)

  • In the first part, the corners of the mouth move to both sides and the mouth flattens. Here, we need to move ab two points to both sides with attribute animation (the corner points on both sides also move), c point to the top, and then return to the original position.
  • The second part is that the two points ab close to the middle until ab coincides, at the same time, the two points ab move upward, and the control points of de elongate at the same time until an ellipse is formed.

incomprehension!! If you don't understand, imagine again, spatial imagination. If you still don't understand, forget it. After all, I don't use much at ordinary times.

12. Bomb lead, ignition effect

The bomb lead effect is also divided into two parts

  • One is that the leader becomes shorter. You can obtain the proportion of Path (such as 70% Path) according to PathMeasure, so that we can draw the effect of leader shortening with a proportion of 0 to 1 through ValueAnimator
//mHeadLinePath is the full Path of the leader
       mPathMeasure.setPath(mHeadLinePath,false);
        mPath.reset();
      mPathMeasure.getSegment(0,mPathMeasure.getLength()*headLinePercent,mPath,true);//Obtain the leader of the corresponding scale according to the scale
        canvas.drawPath(mPath,mPaint);
  • The second part is the effect of ignition. In fact, it is a golden solid circle, then a red circle border, white in the middle, and the three circles are animated to zoom in and out at different rates and limits (the original design also adds the function of color change, and the golden circle will change color, which can be realized by argbvaluator).

13. Explosion animation

And the leader animation type, 4 circles are animated to zoom in and out, only after reaching a certain size, then the circle is small and empty, and the empty is gradually enlarged.

Original link: http://www.jianshu.com/p/a622...

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!

Topics: Android Back-end