这是映客app点赞动画效果,如图
![image](http://upload-images.jianshu.io/upload_images/8958728-681a7e3b302d7119?imageMogr2/auto-orient/strip)
<a name="t0" style="box-sizing: border-box; background: transparent; color: rgb(79, 161, 219); text-decoration: none; margin: 0px; padding: 0px; font-weight: 400; outline: 0px;"></a> 动画分析
当我们触摸屏幕的时候,会在右下方有心型的图案并且不断向上。这是直接看到的部分,仔细分析,我们可以分为以下部分。
1、当点击时,心形图案从无到有弹出动画。
2、心形图案沿着不规则路径从下往上运动,直至消失,并且通过仔细观察我们可以认为运动轨迹基本按照S形路径运动。
所以,在操作的时候,我们按照一跟二的动画效果完成点赞效果。
3、结合1、2的动画效果,我们需要做时间与位置的控制。
<a name="t1" style="box-sizing: border-box; background: transparent; color: rgb(79, 161, 219); text-decoration: none; margin: 0px; padding: 0px; font-weight: 400; outline: 0px;"></a> 技术分析
1、对于分析中心形图案弹出动画,我们可以用阻尼动画,Spring动画做设置。
2、心形动画的路径我们可以利用UIBezierPath绘制,我们利用arc4random_uniform(2)生产随机数的方法,生产绘制S形曲线所需的两个点。利用CAKeyframeAnimation动画,可以设置CALayer的起始点,中间关键点,终点的frame。时间,动画会沿着设定的轨迹执行。
3、心形动画消失,UIView animateWithDuration:time aniamtions:^{}方法,改时间应该小于CAKeyframeAnimation设定的动画运动时间,突出不规则运功。
<a name="t2" style="box-sizing: border-box; background: transparent; color: rgb(79, 161, 219); text-decoration: none; margin: 0px; padding: 0px; font-weight: 400; outline: 0px;"></a> 基本代码实现
NSTimeInterval totalAnimationDuration = 6;
CGFloat heartSize = CGRectGetWidth(self.bounds);
CGFloat heartCenterX = self.center.x;
CGFloat viewHeight = CGRectGetHeight(view.bounds);
//Pre-Animation setup
self.transform = CGAffineTransformMakeScale(0, 0);
self.alpha = 0;
//心形弹出阻尼动画
[UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.6 initialSpringVelocity:0.8 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.transform = CGAffineTransformIdentity; //重置 开始弹出
self.alpha = 0.9;
} completion:NULL];
//生成随机数
NSInteger i = arc4random_uniform(2); //随机数
NSInteger rotationDirection = 1- (2i);// -1 OR 1
NSInteger rotationFraction = arc4random_uniform(10);
[UIView animateWithDuration:totalAnimationDuration animations:^{
self.transform = CGAffineTransformMakeRotation(rotationDirection * PI/(16 + rotationFraction0.2));
} completion:NULL];
//画S形曲线
UIBezierPath *heartTravelPath = [UIBezierPath bezierPath];
[heartTravelPath moveToPoint:self.center];
//r随机的终点
CGPoint endPoint = CGPointMake(heartCenterX + (rotationDirection) * arc4random_uniform(2*heartSize), viewHeight/6.0 + arc4random_uniform(viewHeight/4.0));
//random Control Points 随机控制点
NSInteger j = arc4random_uniform(2);
NSInteger travelDirection = 1- (2*j);// -1 OR 1
//随机的X和Y为控制点
CGFloat xDelta = (heartSize/2.0 + arc4random_uniform(2*heartSize)) * travelDirection;
CGFloat yDelta = MAX(endPoint.y ,MAX(arc4random_uniform(8*heartSize), heartSize));
CGPoint controlPoint1 = CGPointMake(heartCenterX + xDelta, viewHeight - yDelta);
CGPoint controlPoint2 = CGPointMake(heartCenterX - 2*xDelta, yDelta);
//方法 Bezier曲线的定义
[heartTravelPath addCurveToPoint:endPoint controlPoint1:controlPoint1 controlPoint2:controlPoint2];
//Keyframe顾名思义就是关键点的frame,你可以通过设定CALayer的始点、中间关键点、终点的frame,时间,动画会沿你设定的轨迹执行。
CAKeyframeAnimation *keyFrameAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
keyFrameAnimation.path = heartTravelPath.CGPath;
keyFrameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
keyFrameAnimation.duration = totalAnimationDuration + endPoint.y/viewHeight; //大于消失的时间。
[self.layer addAnimation:keyFrameAnimation forKey:@"positionOnPath"];
//图案消失
[UIView animateWithDuration:totalAnimationDuration animations:^{
self.alpha = 0.0;
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
基本点就是,阻尼动画,随机点确定贝塞尔曲线,动画沿着贝塞尔曲线执行,最后渐变消失。