"iOS effect set" to achieve QQ to eliminate the red dot (one-click backward) effect

Source: Internet
Author: User
Tags cos sin

QQ sticky Little Red dot is very fun has wood, so I also want to achieve some, see iOS implementation of less people, Android more, so this is using iOS to achieve HA ~

Debug diagram:

In fact, in terms of implementation, I first realized the effect of the second picture.

Implementation ideas

1. Understand the principle and how to draw a "sticky" shape (i.e. draw two circles plus two Bezier curves).

2. New UIView (Azmetaballcanvas), as a separate canvas for drawing "sticky" shape, the program implementation algorithm, and draw out.

3. Add a method to the canvas (Azmetaballcanvas) attach:(UIView *) and add a gesture listener to redraw it so that any view can have a "sticky" effect on the canvas.

4. Depending on the distance of the connecting line and judging whether or not to disconnect, the user's finger should be judged by distance to explode animation or rebound animation.

Detailed procedures

First of all we must understand the small red dot drag the process shape is what, in fact, is similar to the meta-ball effect (metaball). Careful observation of the analysis found that two different sizes of the circle plus two Bezier curve composition.

About the algorithm part, I have broken down into another blog post, it is strongly suggested that the shape is how to draw the students first look at the "algorithm analysis" QQ "a key to return" the detailed method of calculation

1. Draw drag

Now that we know how to draw the coordinate points, we can go to the realization.

Start by creating a new "canvas" that inherits fromUIView

//AZMetaBallCanvas.h@interface AZMetaBallCanvas : UIView@property(nonatomic,strong) Circle *centerCircle;@property(nonatomic,strong) Circle *touchCircle;@end

CircleTo customize the entity class, it defines some of the basic properties of the circle, such as the center coordinate, radius, and so on.

Why create a new canvas?

Because the small red dot is able to drag the full screen, although QQ on it there is a line Cell , but in fact you can pull it to other Cell up, this need to small red dot enough to draw, simply create a new canvas dedicated to the small red dots to draw the action good.

AZMetaBallCanvasCurrently contains two properties, two circles, a central circle, a touch circle, according to demand, the center circle should be the same position, the touch circle will follow the finger to touch the position of the screen, and then need to draw a Bezier curve between the two circles to form a meta-sphere effect.

The next thing AZMetaBallCanvas to start writing is the implementation

//AZMETABALLCANVAS.M#define RADIUS 40.0 @interface azmetaballcanvas() {Uibezierpath *_path;Cgpoint_touchpoint;}@end @implementation azmetaballcanvas -(Instancetype) Initwithcoder: (Nscoder *) Adecoder { Self= [SuperInitwithcoder:adecoder];NSLog(@"Initwithcorder");if( Self) {        [ SelfInitData]; }return  Self;} - (void) InitData {_touchcircle = [Circle initwithcenterpoint: Self. CenterRadius:radius]; _centercircle = [Circle initwithcenterpoint: Self. CenterRadius:radius]; _touchpoint = Self. Center;NSLog(@"Self.center (%f,%f)", Self. Center. x, Self. Center. Y);}@end

Initializes the position of the two circles, defaults to View the center, and joins the init initWithFrame custom initialization method in the,, and so on initWithCoder parent class constructors initData .

overriding drawing methods

Like in Android onDraw() , iOS drawRect can be overridden to draw and then called [view setNeedsDisplay] to notify redraw.

- (void)drawRect:(CGRect)rect {    _path = [[UIBezierPath alloc] init];    [self drawCenterCircle];    [self drawTouchCircle:_touchPoint];    [self drawBezierCurveWithCircle1:_centerCircle Circle2:_touchCircle];}

As described in the algorithm analysis, when drawing, we only need to draw two circle ( drawCenterCircle , drawTouchCircle ) and connect two circles Bezier curve ( drawBezierCurve ), the algorithm is actually copied "algorithm analysis" QQ "one key backward" of the detailed calculation method

iOS comes with Bezier curves UIBezierPath , with its own circle method addArcWithCenter: radius: startAngle: endAngle: clockwise: , so we just call it!

#pragmaMark Draw Circle---Circle- (void) drawcentercircle {[self Drawcircle:_path circle:_centercircle];} - (void) drawtouchcircle:(cgpoint)Center {_touchcircle. Center Point= Center; [Self DrawCircle:_Path Circle:_TouchCircle];}- (void)drawcircle:(uibezierpath *)path circle:(Circle *)Circle {[ _path addarcwithcenter:circle. Center PointRadius:circle.radius startAngle:0 EndAngle: theClockwise:true]; [_Path fill]; [_Path stroke]; [_Path removeallpoints];}
#pragma mark Draw curve---draw Bezier curves- (void) DrawBezierCurveWithCircle1: (Circle *) Circle1 Circle2: (Circle *) Circle2 {floatcircle1_x = Circle1.centerpoint.x;floatcircle1_y = Circle1.centerpoint.y;floatcircle2_x = Circle2.centerpoint.x;floatcircle2_y = Circle2.centerpoint.y;//The length of the Connecting Heart line    floatD =sqrt(POWF (circle1_x-circle2_x,2) + POWF (circle1_y-circle2_y,2));///The angle of the x-axis of the connecting Heart line    floatAngle1 =Atan((circle2_y-circle1_y)/(circle1_x-circle2_x));//The angle of the connecting line and the Gongsche    floatAngle2 =ASIN((Circle1.radius-circle2.radius)/d);//Tangent to center point and x-axis angle    floatAngle3 = M_pi_2-angle1-angle2;floatAngle4 = M_pi_2-angle1 + angle2;floatoffset1_x =Cos(angle3) * Circle1.radius;floatOffset1_y =Sin(angle3) * Circle1.radius;floatoffset2_x =Cos(angle3) * Circle2.radius;floatOffset2_y =Sin(angle3) * Circle2.radius;floatoffset3_x =Cos(angle4) * Circle1.radius;floatOffset3_y =Sin(angle4) * Circle1.radius;floatoffset4_x =Cos(angle4) * Circle2.radius;floatOffset4_y =Sin(angle4) * Circle2.radius;floatp1_x = circle1_x-offset1_x;floatp1_y = circle1_y-offset1_y;floatp2_x = circle2_x-offset2_x;floatp2_y = circle2_y-offset2_y;floatp3_x = circle1_x + offset3_x;floatp3_y = circle1_y + offset3_y;floatp4_x = circle2_x + offset4_x;floatp4_y = circle2_y + offset4_y;    Cgpoint P1 = Cgpointmake (p1_x, p1_y);    Cgpoint P2 = cgpointmake (p2_x, p2_y);    Cgpoint p3 = Cgpointmake (p3_x, p3_y);    Cgpoint P4 = Cgpointmake (p4_x, p4_y); Cgpoint P1_CENTER_P4 = Cgpointmake ((p1_x + p4_x)/2, (p1_y + p4_y)/2); Cgpoint p2_center_p3 = Cgpointmake ((p2_x + p3_x)/2, (p2_y + p3_y)/2);    [Self drawbeziercurvestartat:p1 endat:p2 controlpoint:p2_center_p3];    [Self drawlinestartat:p2 ENDAT:P4];    [Self drawbeziercurvestartat:p4 endat:p3 CONTROLPOINT:P1_CENTER_P4];    [Self drawlinestartat:p3 endat:p1];    [_path MOVETOPOINT:P1];    [_path Closepath]; [_path stroke];}
2. Listening gesture Simple version

The simplest is actually a series of AZMetaBallCanvas methods that are rewritten directly in touchXXX , and then in which the call notification is redrawn setNeedsDisplay UIView .

#pragma mark touch event- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {    UITouch *touch = [touches anyObject];    _touchPoint = [touch locationInView:self];    [self setNeedsDisplay];}- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {    UITouch *touch = [touches anyObject];    _touchPoint = [touch locationInView:self];    [self setNeedsDisplay];}

Now actually almost the second picture of the effect has come out, the difference is to change the radius of the two circle method.

The way to change the radius is very simple.

#pragma 改变半径-(void)changeCenterCircleRadiusTo:(float)radius {    _centerCircle.radius = radius;    [self setNeedsDisplay];}-(void)changeTouchCircleRadiusTo:(float)radius {    _touchCircle.radius = radius;    [self setNeedsDisplay];}
Normal edition

According to the phenomenon found, we need to drag the little red dots to move it, rather than our hands pointing, where the Little red dot, so we need to give the little red dot to increase gesture monitoring, rather than the "canvas."

Instead, we add a method to the canvas - (void)attach:(UIView *)item; and then add gestures to the incoming view Pan .

- (void) Attach: (UIView*) Item {Uipangesturerecognizer *drag = [[Uipangesturerecognizer alloc] Initwithtarget: SelfAction@selector(drag:)]; Item. userinteractionenabled=YES; [Item Addgesturerecognizer:drag];} - (void) Drag: (Uipangesturerecognizer *) Recognizer {//Get Touch point_touchpoint = [Recognizer Locationinview: Self];//Get Touch View    UIView*touchview = recognizer. View;Switch(recognizer. State) { Caseuigesturerecognizerstatebegan:{//touch Start: Draw a copy of the Touchview on the canvas            //... This section see the source code             Break; } Caseuigesturerecognizerstatechanged:{//move: Record touch position, change coordinate position of Touchview and Touchcircle[ SelfResettouchcenter:_touchpoint]; Break; } CaseUigesturerecognizerstateended: {//touch End: Judging by the length of the centerline is the execution of an exploded animation or a spring animation            //... This section see the source code             Break; }default: Break; }    [ SelfSetneedsdisplay];// Redraw}

Because the code is more, all paste will be messy, so I use the language description instead of paste code, need to source the students can go to the bottom of the article to download.

SOURCE Address: Https://github.com/Xieyupeng520/AZMetaBall ((づ ̄3 ̄) づ╭?~ seeking the Stars)

"iOS effect set" to achieve QQ to eliminate the red dot (one-click backward) effect

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.