Animation effect 7: collision animation, animation effect collision

Source: Internet
Author: User

Animation effect 7: collision animation, animation effect collision

The animation effect described in this section is a collision animation, that is, the Collision Effect of a simulated or simulated real object. Let's take a look.



Animation Effect Analysis:

1. There are two forms of the same View (self and opponent), so we can consider encapsulating a View directly.

2. Note that the image in the View and the circle in the border may become an elliptical shape. Therefore, using the View block Method to achieve this effect is a bit unreliable. We can consider using layer animation.

The hierarchical structure of View is as follows:



1. Because each View has its own name, the encapsulated View inherits from UIView rather than UIImageView.

2. photoLayer is used to display images.

3. maskLayer is used to achieve the rounded corner effect.

4. circleLayer is the circle outside the image.

With the above analysis, we can customize the View (AvatarView) of an avatar and it should have two attributes: Image and name.

@property (nonatomic, strong) UIImage *image;@property (nonatomic, copy) NSString *name;

Then, initialize the file in the AvaterView. m file.

- (instancetype)initWithCoder:(NSCoder *)aDecoder {    if (self = [super initWithCoder:aDecoder]) {        [self initSubs];    }    return self;}- (instancetype)initWithFrame:(CGRect)frame {    if (self = [super initWithFrame:frame]) {        [self initSubs];    }    return self;}- (void)initSubs {    self.photoLayer = [CALayer layer];    self.circleLayer = [CAShapeLayer layer];    self.maskLayer = [CAShapeLayer layer];    self.label = [[UILabel alloc] init];    self.label.font = [UIFont fontWithName:@"ArialRoundedMTBold" size:18.0];    self.label.textAlignment = NSTextAlignmentCenter;    self.label.textColor = [UIColor blackColor];        [self.layer addSublayer:self.photoLayer];    self.photoLayer.mask = self.maskLayer;    [self.layer addSublayer:self.circleLayer];    [self addSubview:self.label];}- (void)setImage:(UIImage *)image {    _image = image;    self.photoLayer.contents = (__bridge id)(image.CGImage);}- (void)setName:(NSString *)name {    _name = [name copy];    self.label.text = name;}

Note that the code self. photoLayer. contents = (_ bridge id) (image. CGImage) is used to draw layer images. The image is directly drawn to the layer, instead of being added to the photoLayer in the form of addsubView or addsubLayer.

Then we layout the elements in AvatarView. The Code is as follows:

- (void)layoutSubviews {    [super layoutSubviews];    //Size the avatar image to fit    CGFloat width = self.bounds.size.width;    CGFloat height = self.bounds.size.height;    CGFloat photoLayerX = (width - self.image.size.width + borderWidth) * 0.5;    CGFloat photoLayerY = (height - self.image.size.height - borderWidth) * 0.5;    self.photoLayer.frame = CGRectMake(photoLayerX, photoLayerY, self.image.size.width, self.image.size.height);        //Draw the circle    self.circleLayer.path = [UIBezierPath bezierPathWithOvalInRect:self.bounds].CGPath;    self.circleLayer.strokeColor = [UIColor whiteColor].CGColor;    self.circleLayer.lineWidth = borderWidth;    self.circleLayer.fillColor = [UIColor clearColor].CGColor;        //Size the layer    self.maskLayer.path = self.circleLayer.path;    self.maskLayer.position = CGPointMake(0, 10);        //Size the label    self.label.frame = CGRectMake(0, height + 10, width, 24);}

BezierPathWithOvalInRect is used to obtain the inner or inner tangent elliptic of a rectangle. Here is a square, so the Avatar is shown in a circle.

Then, call the custom AvatarView in the viewDidload method of ViewController and complete its initialization. The Code is as follows:

- (void)viewDidLoad {    [super viewDidLoad];       self.opponentAvatar.image = [UIImage imageNamed:@"empty"];    self.myAvatar.image = [UIImage imageNamed:@"avatar-1"];    self.myAvatar.name = @"Me";}

At this point, the UI effect is as follows:



Analysis of collision animation.

They look like a collision animation. In essence, they are used to bring two views closer to each other. When the two views reach a certain position (that is, when they meet each other), they change the presentation form (elliptical) of photoLayer and circleLayer ).

We use the center of the screen as the baseline. When the two finally collide, the X values of their center points are: the center of the screen x-Avatar width/2, and the center of the screen x + Avatar width/2. The code for the final collision between the two is as follows:

CGSize avatarSize = self. myAvatar. frame. size; // theoretically, the bounceXOffset value is avatarSize. width/2, but considering the image has a border, adjust CGFloat bounceXOffset = avatarSize as appropriate. width/1.9; CGSize morphSize = CGSizeMake (avatarSize. width * 0.85, avatarSize. height * 1.1); CGPoint rightBouncePoint = CGPointMake (self. view. frame. size. width * 0.5 + bounceXOffset, self. myAvatar. center. y); CGPoint leftBouncePoint = CGPointMake (self. view. frame. size. width * 0.5-bounceXOffset, self. myAvatar. center. y );

The preceding variables bounceXOffset and morphSize are described as follows:

1. The deviation distance should be the Avatar width/2, but here is divided by 1.9, the purpose is to achieve more obvious elliptical display when a collision occurs.

2. morphSize is the form of collision between the two. It is obvious that the width of the original avatar is compressed and the height is stretched. In this way, when we get the inner-cut image, we will see the elliptical effect.

Define a method in AvatarView to take charge of the animation Collision Effect.

- (void)bounceOffPoint:(CGPoint)bouncePoint morphSie:(CGSize)morphSize;


1. The two are close to each other and are executed cyclically.

Write the following code in the method defined above.

CGPoint originalCenter = self. center; // The smaller the Damping value, the greater the elasticity [UIView animateWithDuration: animationDuration delay: 0.0 usingSpringWithDamping: 0.8 initialSpringVelocity: 0.0 options: Invalid animations: ^ {self. center = bouncePoint;} completion: ^ (BOOL finished) {}]; [UIView Duration: animationDuration delay: animationDuration usingSpringWithDamping: 0.7 initialSpringVelocity: 0.1 options: Invalid animations: ^ {self. center = originalCenter;} completion: ^ (BOOL finished) {dispatch_after (dispatch_time (DISPATCH_TIME_NOW, (int64_t) (1.0 * NSEC_PER_SEC), interval (), ^ {<span style = "white-space: pre"> </span> [self bounceOffPoint: bouncePoint morphSie: morphSize] ;});}];

Before executing the animation, first save the original center point with the originalCenter variable, and then use the spring animation to move the Avatar to the collision point. Stay for 1 second, and then use a similar spring animation to execute the above animation cyclically. This completes the effect of the two approaching and repeating. As follows:


2. collision is an elliptical Effect

- (void)bounceOffPoint:(CGPoint)bouncePoint morphSie:(CGSize)morphSize;
Add the following code at the bottom of the above method

CGRect rightMorphFrame = CGRectMake(0, self.bounds.size.height - morphSize.height, morphSize.width, morphSize.height);    CGRect leftMorphFrame = CGRectMake(self.bounds.size.width - morphSize.width, self.bounds.size.height - morphSize.height, morphSize.width, morphSize.height);    CGRect morphedFrame = (originalCenter.x > bouncePoint.x) ? rightMorphFrame : leftMorphFrame;        CABasicAnimation *morphAnimation = [CABasicAnimation animationWithKeyPath:@"path"];    morphAnimation.duration = animationDuration;    morphAnimation.toValue = (__bridge id)([UIBezierPath bezierPathWithOvalInRect:morphedFrame].CGPath);    morphAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];        [self.circleLayer addAnimation:morphAnimation forKey:nil];    [self.maskLayer addAnimation:morphAnimation forKey:nil];

Let the two pictures View the path effect of the CABasicAnimation animation. The value of toValue is the elliptical effect of the morphedFrame, so the collision between the two results in the visual oval effect.

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

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.