The beauty of trigonometric functions-water ripple loading Loadingview

Source: Internet
Author: User

First, preface

Study is to summarize, in recent days to learn the drawing related, but the use of less opportunities, and now almost forgotten, this time to see the water ripple of the drawing, feel very interesting, or the realization of the method recorded. Technology without him, for hand-cooked, or to practice more, empty light endangers, hard work Hing bang, let us look at today's triangle function of the beauty bar.

Ii. Overview

Certainly everyone is not unfamiliar with the triangle function of middle school study, but the study of sin, cos is a function of transcendental function, is a kind of elementary function, borrowed a picture of Wikipedia:


A complete sine function should be this: >y=asin (ωx+φ) +h,a determines the peak, Ω determines the period, φ represents the initial phase, and H represents the position of the y-axis. In Android we use the general is Math.sin (30*math.pi/180) This form, I originally do not understand the meaning of this writing, later only understand Math.PI is π,π namely 180 degrees, so the above equation equivalent to sin (Π/6) =1/2, In high school we are generally sin (30°) =1/2, which assigns x in sin (x) as an angle, whereas in computer language x is usually radians.


This flow interface is through the SIN function curve constantly changing the x position to draw, the way of implementation certainly there are other methods, through the drawing Bezier curve also has the implementation of the case, we will use the example of the water ripple Loadingview drawing, well, not much to say, Hands-on take you step by step to achieve beautiful cool loading water ripple effect.

Three, the implementation of the Wave control

First, we first implement the rendering of the wave control:
Calculate the coordinate points first:

//这里我们以view的总宽度为周期,y = a * sin(2π) + b        for (int0; i < mTotalWidth; i++){            mPointY[i] = (float) (20 * (Math.sin2 * Math.PI * i / w)));        }

Drawing curves

fori0;ii++){            canvas.drawLine(i,mTotalHeight - mDaymicPointY[i] - 300,i,mTotalHeight,mPaint);        }

Minus 300 here is to control the position on the y-axis, we can dynamically set a value, move up and down the view to reach the traffic interface, we first step.
Control movement

//改变两条波纹的移动点        mXoffset += X_SPEED;        //如果已经移动到末尾处,则到头重新移动        if(mXoffset > mTotalWidth){            0;        }
// 超出屏幕的挪到前面,mXoffset表示第一条水波纹要移动的距离        int yIntelrval = mPointY.length - mXoffset;        //使用System.arraycopy方式重新填充第一条波纹的数据        0, mDaymicPointY, mXoffset, yIntelrval);        0, mXoffset);

Now you will find a simple water ripple effect coming out as shown in:

You will find this water ripple with our effect is still some gap, don't worry, we also have this class Porterduffxfermode, can be implemented with the drawing of the image according to a certain rule to mix, to form a new pixel value, then we can draw a water ripple effect, and then draw a circle, Use the following diagram to mix, you will find a miracle, Porterduffxfermode related use can refer to this blog:

Porterduffxfermode use and working principle of canvas drawing in Android


What kind of rules to use, their own to find Bai, are to carry out some kind of rules to mix, I found, using the srcin, can be mixed to achieve the effect of
Now this is the effect, we are adding a seekbar, drag the display effect, basically can appear this wave loading effect

        intCanvaswidth =Canvas. GetWidth ();intCanvasheight =Canvas. GetHeight ();intLayerid =Canvas. Savelayer (0,0, canvaswidth, canvasheight, NULL, Canvas.all_save_flag);Canvas. drawcircle (Mtotalwidth/2, Mtotalheight/2, Mtotalwidth/2, Mcriclepaint);//Set color blending modeMpaint.setxfermode (New Porterduffxfermode (PorterDuff.Mode.SRC_IN));//high minus width divided by 2 to make the water ripple bottom at the bottom of the circle, dynamically change the percent value, change on the y axis             for(inti =0; i < mtotalwidth; i++) {Canvas. DrawLine (i, Mtotalheight-mdaymicpointy[i]-(mtotalheight-mtotalwidth)/2-percent* Mtotalwidth/ -, I, Mtotalheight-(mtotalheight-mtotalwidth)/2, Mpaint); }///finally remove the brush XfermodeMpaint.setxfermode (NULL);//Change the moving point of two ripplesMxoffset + = X_speed;//If you have moved to the end, the head is moved again            if(Mxoffset > Mtotalwidth) {Mxoffset =0; }Canvas. Restoretocount (Layerid);

The effect is as shown

I put down all the code to implement the process:

 Public  class waveview extends View {    PrivatePaint Mpaint, Mcriclepaint,mtextpaint;//Tilt or rotate, fast change, when a line is drawn on the screen, there is no aliasing,    //But when you draw diagonally, you'll get jagged effects, so you'll need to set anti-aliasing    PrivateDrawfilter Mdrawfilter;Private intMtotalheight, Mtotalwidth;Private intMxoffset =0;Private float[] mpointy;Private float[] mdaymicpointy;//Wave line movement speed    Private Static Final intX_speed = -;Private intPercent Public void setpercent(intpercent) { This. percent = percent; } Public Waveview(Context context) {Super(context);    Init (); } Public Waveview(context context, AttributeSet attrs) {Super(context, attrs);    Init (); } Public Waveview(context context, AttributeSet attrs,intDEFSTYLEATTR) {Super(Context, attrs, defstyleattr);    Init (); }Private void Init() {//Picture Line (Universal) anti-aliasing needs to be set separatelyMdrawfilter =NewPaintflagsdrawfilter (0, Paint.anti_alias_flag | Paint.filter_bitmap_flag);//Instantiate a brushMpaint =NewPaint ();//Remove brush aliasingMpaint.setantialias (true);//Set brush style to solid lineMpaint.setstyle (Paint.Style.FILL);//Set Brush colorMpaint.setcolor (Color.green);//Instantiate a circle brushMcriclepaint =NewPaint (Mpaint); Mcriclepaint.setcolor (Color.parsecolor ("#88dddddd")); Mcriclepaint.setalpha (255);//instanced text BrushMtextpaint =NewPaint (); Mtextpaint.setantialias (true); }@Override    protected void OnDraw(Canvas canvas) {Super. OnDraw (canvas);//antialiasingCanvas.setdrawfilter (Mdrawfilter); Runwave ();intCanvaswidth = Canvas.getwidth ();intCanvasheight = Canvas.getheight ();intLayerid = Canvas.savelayer (0,0, Canvaswidth, Canvasheight,NULL, Canvas.all_save_flag); Canvas.drawcircle (Mtotalwidth/2, Mtotalheight/2, Mtotalwidth/2, Mcriclepaint);//Set color blending modeMpaint.setxfermode (NewPorterduffxfermode (PorterDuff.Mode.SRC_IN));//high minus width divided by 2 to make the water ripple bottom at the bottom of the circle, dynamically change the percent value, change on the y axis             for(inti =0; i < mtotalwidth; i++) {canvas.drawline (i, Mtotalheight-mdaymicpointy[i]-(mtotalheight-mtotalwidth)/2-percent * Mtotalwidth/ -, I, Mtotalheight-(mtotalheight-mtotalwidth)/2, Mpaint); }///finally remove the brush XfermodeMpaint.setxfermode (NULL);//Change the moving point of two ripplesMxoffset + = X_speed;//If you have moved to the end, the head is moved again            if(Mxoffset > Mtotalwidth) {Mxoffset =0;        } canvas.restoretocount (Layerid); String Text = percent +"%"; Mtextpaint.settextsize ( the);floatTextLength = Mtextpaint.measuretext (text); Canvas.drawtext (text, (mtotalwidth-textlength)/2, Mtotalheight/2- -, Mtextpaint);//Cause view redrawPostinvalidatedelayed ( -); }@Override    protected void onsizechanged(intWintHintOLDW,intOLDH) {Super. onsizechanged (W, H, OLDW, OLDH);        Mtotalheight = h; Mtotalwidth = W;//The length of the array is the width of the viewMpointy =New float[W]; Mdaymicpointy =New float[W];//Here we take the total width of the view as the period, y = a * sin (2π) + b         for(inti =0; i < mtotalwidth; i++) {Mpointy[i] = (float) ( -* (Math.sin (2* Math.PI * i/w)); }    }Private void Runwave() {//Beyond the screen to the front, mxoffset means the first water ripple to move the distance        intYintelrval = Mpointy.length-mxoffset;//re-populate the first ripple data using the System.arraycopy methodSystem.arraycopy (Mpointy,0, Mdaymicpointy, Mxoffset, Yintelrval); System.arraycopy (Mpointy, Yintelrval, Mdaymicpointy,0, Mxoffset); }}

Above is the implementation of all the code, there are comments, I believe we can understand, in fact, to achieve these effects is very simple, but we also have a lot of expansion of the place, a network to load the waiting animation, or make a download of the progress, waiting for everyone to achieve.

Source code later upload

The beauty of trigonometric functions-water ripple loading Loadingview

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.