Custom little sun control and little sun Control

Source: Internet
Author: User
Tags getcolor

Custom little sun control and little sun Control

 

 

 

 

 

You are not mistaken. The circle in the upper right corner is the legend of the sun, ^ _ ^

The difficulty of this animation lies in the preparation of the "food". You don't have to worry about it. You still haven't got it wrong. Those little points are the legendary food.

First, step by step, to see this effect, the first thing we think of is a normal small circle, and this big circle is drawn by besell. As to why is it not just a semi-circle, because the food is centered around the semi-circle and closely following it, you need to take this semi-circle as a reference object. Otherwise, the layout will be changed randomly,

Then the small circle also needs to circle around the semi-circle, both of which need a known point

Next we will start to draw the semi-circle, and the small circle will be ignored directly.

The semi-circle is drawn using drawPath. cubicTo. Four vertices are required, including two control points.

How to draw the code?

Next, some people may be confused about how to draw food and how to keep food close to this semi-circle. Can I change the Y axis according to this semi-circle, in this way, the other half circle appears, but the style needs to be changed, because the food is a small dot.

Set the paint effect here to change the painting style.

In this way, the food appears.

Then there is a difficulty. How can we eat a circle along the food? Obviously, we cannot draw it directly based on the food method, because the circle is moving and we need to add an animation, instead of drawing them all at once, we need to know the coordinates of the food so that we can eat the circle around the food.

Here, Evaluator is used to calculate a coordinate for drawing itself based on the control point. besell is a formula that can calculate a coordinate point.

Package com. fragmentapp. view; import android. graphics. pointF;/*** Created by liuzhen on 2018/1/24. */public class BezierUtil {/*** B (t) = (1-t) ^ 2 * P0 + 2 t * (1-t) * P1 + t ^ 2 * P2, t ε [0, 1] ** @ param t curve length ratio * @ param p0 start point * @ param p1 Control Point * @ param p2 end point * @ return t corresponding point */public static pointF CalculateBezierPointForQuadratic (float t, pointF p0, PointF p1, PointF p2) {PointF point = new PointF (); float temp = 1-t; point. x = temp * temp x + 2 * t * temp * p1.x + t * p2.x; point. y = temp * temp y + 2 * t * temp * p1.y + t * p2.y; return point;}/*** B (t) = P0 * (1-t) ^ 3 + 3 * P1 * t * (1-t) ^ 2 + 3 * P2 * t ^ 2 * (1-t) + P3 * t ^ 3, t ε [0, 1] ** @ param t curve length ratio * @ param p0 start point * @ param p1 Control Point 1 * @ param p2 Control Point 2 * @ param p3 end point * @ return t corresponding vertex */public static PointF CalculateBezierPointForCubic (float t, pointF p0, PointF p1, PointF p2, PointF p3) {PointF point = new PointF (); float temp = 1-t; point. x = temp x * temp + 3 * p1.x * t * temp + 3 * p2.x * t * temp + p3.x * t; point. y = Policy * temp + 3 * p1.y * t * temp + 3 * p2.y * t * temp + p3.y * t; return point ;}}
View Code
package com.fragmentapp.view;import android.animation.TypeEvaluator;import android.graphics.PointF;/** * Created by liuzhen on 2018/1/24. */public class PathEvaluator implements TypeEvaluator<PointF> {    private PointF mControlPoint1,mControlPoint2;//    public PathEvaluator(PointF controlPoint) {//        this.mControlPoint1 = controlPoint;//    }    public PathEvaluator(PointF controlPoint1,PointF controlPoint2) {        this.mControlPoint1 = controlPoint1;        this.mControlPoint2 = controlPoint2;    }    @Override    public PointF evaluate(float t, PointF startValue, PointF endValue) {        return BezierUtil.CalculateBezierPointForCubic(t, startValue, mControlPoint1,mControlPoint2, endValue);    }}
View Code

 

With these coordinates, the circle can be eaten along the food, but with the food action, we will find how to eat this problem. This is obviously not a good operation. I thought for a while, I found that this road was not feasible, and the technology was not up to standard. So I made a different path and used another method. I thought it was to draw a line with the background color.

In this way, the food will be eaten, so there is a clears. add operation on it.

Add a mouth to the circle.

To control the angle parameter, the circle can finally be eaten, and then add a moving animation to pursue a higher level. Then, when the animation starts, let the semi-circle have a rising process, it suddenly seems a little tall.

Last stop

Two methods are used, one is the start animation, the other is the start animation, and the other two are called at the right time, and the code is directly added.

Package com. fragmentapp. view. refresh; import android. animation. valueAnimator; import android. content. context; import android. graphics. canvas; import android. graphics. dashPathEffect; import android. graphics. matrix; import android. graphics. paint; import android. graphics. path; import android. graphics. pathDashPathEffect; import android. graphics. pathEffect; import android. graphics. pointF; import android. graphics. R EctF; import android. util. attributeSet; import android. util. log; import android. view. view; import android. view. animation. linearInterpolator; import com. fragmentapp. r; import com. fragmentapp. helper. timeUtil; import com. fragmentapp. view. pathEvaluator; import java. util. arrayList; import java. util. list;/*** Created by liuzhen on 2018/1/24. */public class SunHeadView extends View implements IHeadView {private Int mWidth; private int mHeight; private Paint effectPaint, facePaint, clearPaint, defPaint; // multiple attributes are defined here to allow you to customize different styles private RectF rectF = null; private float angle, loadAngle = 45; private ValueAnimator faceVa, arcVa; private int left, top; private boolean isDraw = false; private Path path, foodPath; private PointF startPoint = null, movePoint1 = null, movePoint2 = null, endPoint = null; private List <Point F> clears = null; private PathEffect effect = null; private int faceRadius = 30, foodRadius = 3; public SunHeadView (Context context) {this (context, null, 0 );} public SunHeadView (Context context, AttributeSet attrs) {this (context, attrs, 0);} public SunHeadView (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr); init ();} private void init () {path = new P Ath (); foodPath = new Path (); foodPath. addCircle (0, 0, foodRadius, Path. direction. CCW); effectPaint = new Paint (); effectPaint. setAntiAlias (true); effectPaint. setStyle (Paint. style. STROKE); effectPaint. setColor (getResources (). getColor (R. color. color_a9a05c); effect = new PathDashPathEffect (foodPath, 12,-1, PathDashPathEffect. style. ROTATE); effectPaint. setPathEffect (effect); facePaint = new Paint (); FacePaint. setAntiAlias (true); facePaint. setStyle (Paint. style. FILL); facePaint. setColor (getResources (). getColor (R. color. color_a9a05c); defPaint = new Paint (); defPaint. setAntiAlias (true); defPaint. setStyle (Paint. style. FILL); defPaint. setColor (getResources (). getColor (R. color. color_a9a05c); rectF = new RectF (0, 0, 0); startPoint = new PointF (); movePoint1 = new PointF (); movePoint2 = new PointF (); EndPoint = new PointF (); clearPaint = new Paint (); clearPaint. setAntiAlias (true); clearPaint. setStyle (Paint. style. FILL); clearPaint. setColor (getResources (). getColor (R. color. white); clears = new ArrayList <> () ;}@ Override protected void onLayout (boolean changed, int left, int top, int right, int bottom) {super. onLayout (changed, left, top, right, bottom); if (changed) {mWidth = getWidth (); mHei Ght = getHeight (); this. left = mWidth/2; this. top = mHeight/3; rectF. set (startPoint. x-faceRadius/2, startPoint. y-faceRadius, startPoint. x + faceRadius/2, startPoint. y) ;}@ Override protected void onDraw (Canvas canvas) {if (! IsDraw) return; // draw the "food" foodPath. reset (); foodPath. moveTo (startPoint. x, startPoint. y); foodPath. cubicTo (movePoint1.x, movePoint1.y, movePoint2.x, movePoint2.y, endPoint. x, endPoint. y); canvas. drawPath (foodPath, effectPaint); // draw the big ball path. reset (); path. moveTo (startPoint. x + faceRadius/2, startPoint. y); path. cubicTo (movePoint1.x, movePoint1.y + faceRadius/2, movePoint2.x, movePoint2.y + faceRadius/2, endPoint. x -FaceRadius/2, endPoint. y); canvas. drawPath (path, defPaint); // eat "food" for (PointF f: clears) {RectF rectF = new RectF (f. x-foodRadius * 2, f. y-foodRadius * 2, f. x + foodRadius * 2, f. y + foodRadius * 2); canvas. drawOval (rectF, clearPaint);} // draw the ball. You need to draw the canvas at the end. drawArc (rectF, angle, 360-angle * 2, true, facePaint) ;}@ Override public View getView () {return this ;} /** start animation */public void upAnim () {if (faceV A! = Null) faceVa. cancel (); faceVa = null; effectPaint. setColor (getResources (). getColor (R. color. color_a9a05c); facePaint. setColor (getResources (). getColor (R. color. color_a9a05c); clearPaint. setColor (getResources (). getColor (R. color. white); defPaint. setColor (getResources (). getColor (R. color. color_a9a05c); startPoint. set (mWidth * 1/2 + faceRadius * 2, mHeight + faceRadius); movePoint1.set (mWidth * 2/3, 0); mov EPoint2.set (mWidth * 5/6, 0); endPoint. set (mWidth-faceRadius * 2, mHeight + faceRadius); clears. clear (); PathEvaluator bezierEvaluator = new PathEvaluator (movePoint1, movePoint2); arcVa = ValueAnimator. ofObject (bezierEvaluator, startPoint, endPoint); arcVa. addUpdateListener (new ValueAnimator. animatorUpdateListener () {// Rao ball mobile @ Override public void onAnimationUpdate (ValueAnimator valueAnimator) {PointF Point = (PointF) valueAnimator. getAnimatedValue (); // if (point. x + faceRadius <= endPoint. x) clears. add (new PointF (point. x, point. y); // Save the moving coordinates. // faceRadius/2 is used to keep the center of the ball in the middle of the ball. set (point. x-faceRadius/2, point. y-faceRadius/2, point. x + faceRadius/2, point. y + faceRadius/2); postInvalidate () ;}}); arcVa. setInterpolator (new LinearInterpolator (); arcVa. setDuration (2000); arcVa. setRepeatMode (Va LueAnimator. RESTART); arcVa. start (); rectF. set (startPoint. x-faceRadius/2, startPoint. y-faceRadius, startPoint. x + faceRadius/2, startPoint. y); angle = loadAngle; faceVa = ValueAnimator. ofFloat (loadAngle, 0); faceVa. addUpdateListener (new ValueAnimator. animatorUpdateListener () {// food eating action @ Override public void onAnimationUpdate (ValueAnimator valueAnimator) {angle = (float) valueAnimator. getAnimatedVa Lue (); postInvalidate () ;}}); faceVa. setInterpolator (new LinearInterpolator (); faceVa. setDuration (1, 500); faceVa. setRepeatMode (ValueAnimator. RESTART); faceVa. setRepeatCount (-1); faceVa. start () ;}@ Override public void startAnim () {// prelude to javastpaint. setColor (getResources (). getColor (R. color. transparent); facePaint. setColor (getResources (). getColor (R. color. transparent); clearPaint. setColor (getResourc Es (). getColor (R. color. transparent); isDraw = true; faceVa = ValueAnimator. ofFloat (0, mHeight + faceRadius); // fl the faceVa. addUpdateListener (new ValueAnimator. animatorUpdateListener () {// food eating action @ Override public void onAnimationUpdate (ValueAnimator valueAnimator) {float val = (float) valueAnimator. getAnimatedValue (); startPoint. set (mWidth * 1/2 + faceRadius * 2, val); movePoint1.set (mWidth * 2/3, 0); moveP Oint2.set (mWidth * 5/6, 0); endPoint. set (mWidth-faceRadius * 2, val); postInvalidate () ;}}); faceVa. setInterpolator (new LinearInterpolator (); faceVa. setDuration (1, 1000); faceVa. setRepeatMode (ValueAnimator. RESTART); faceVa. start () ;}@ Override public void stopAnim () {if (arcVa! = Null) arcVa. cancel (); if (faceVa! = Null) faceVa. cancel (); arcVa = null; faceVa = null; isDraw = false ;}}
View Code

Finally, welcome to favorites

GitHub: https://github.com/1024477951/FragmentApp

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.