粘性动画DIY

理想效果

实际效果

思考

1.位置上的变化(spring动画)

UIView
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);

<p>

CASpringAnimation
 NS_AVAILABLE_IOS(9_0);

<p>

facebook/pop

pop@github

UIView CASpringAnimation facebook/Pop
方便用,效果一般,但是不灵活,功能不强 iOS9 功能强大,效果好,但是复杂

<p>
<p>

2.形态上的变化(变小,圆边的弧度挤压)

CGAffineTransform/CATransform3D
CGAffineTransformMakeScale(CGFloat sx,CGFloat sy)

<p>
<p>
<p>
<p>

学习

KYAnimatedPageControl(@github)
实现原理

三阶贝塞尔曲线拟合1/4圆

带入三个点计算。


h = 0.552;

CGFloat extra = (self.currentRect.size.width * 2 / 5) * factor;//factor 0~1  随时间变化

CGFloat offset = self.currentRect.size.width / 3.6;  //设置2/0.552 = 3.6 出来的弧度拟合1/4圆形

CGPoint pointA = CGPointMake(rectCenter.x ,self.currentRect.origin.y + extra);
CGPoint pointB = CGPointMake( rectCenter.x + self.currentRect.size.width/2,rectCenter.y);
CGPoint pointC = CGPointMake(rectCenter.x ,rectCenter.y + self.currentRect.size.height/2 - extra);
CGPoint pointD = CGPointMake(self.currentRect.origin.x, rectCenter.y);//..有省略..

CGPoint c1 = CGPointMake(pointA.x + offset, pointA.y); 
CGPoint c2 = CGPointMake(pointB.x, pointB.y - offset);
CGPoint c3 = CGPointMake(pointB.x, pointB.y + offset); 
CGPoint c4 = CGPointMake(pointC.x + offset, pointC.y);
CGPoint c5 = CGPointMake(pointC.x - offset, pointC.y); 
CGPoint c6 = CGPointMake(pointD.x, pointD.y + offset);
CGPoint c7 = CGPointMake(pointD.x, pointD.y - offset); 
CGPoint c8 = CGPointMake(pointA.x - offset, pointA.y);

UIBezierPath* ovalPath = [UIBezierPath bezierPath]; 
[ovalPath moveToPoint: pointA];
[ovalPath addCurveToPoint:pointB controlPoint1:c1 controlPoint2:c2]; 
[ovalPath addCurveToPoint:pointC controlPoint1:c3 controlPoint2:c4];
[ovalPath addCurveToPoint:pointD controlPoint1:c5 controlPoint2:c6]; 
[ovalPath addCurveToPoint:pointA controlPoint1:c7 controlPoint2:c8]; 
[ovalPath closePath]; 

CGContextAddPath(ctx, ovalPath.CGPath);
CGContextSetFillColorWithColor(ctx, self.indicatorColor.CGColor);
CGContextFillPath(ctx);
关键帧动画 (对应参数factor)
CAKeyframeAnimation

阻尼振动






-(NSMutableArray *) springAnimationValues:(id)fromValue toValue:(id)toValue usingSpringWithDamping:(CGFloat)damping initialSpringVelocity:(CGFloat)velocity duration:(CGFloat)duration{
    
    //60个关键帧
    NSInteger numOfFrames  = duration * 60;
    NSMutableArray *values = [NSMutableArray arrayWithCapacity:numOfFrames];
    for (NSInteger i = 0; i < numOfFrames; i++) {
        [values addObject:@(0.0)];
    }
    CGFloat diff = [toValue floatValue] - [fromValue floatValue];
    for (NSInteger frame = 0; frame<numOfFrames; frame++) {
            
       CGFloat x = (CGFloat)frame / (CGFloat)numOfFrames;
        CGFloat value = [toValue floatValue] - diff * (pow(M_E, -damping * x) * cos(velocity * x)); // y = 1-e^{-5x} * cos(30x)
            
        values[frame] = @(value);
    }
    return values;
    
}

<p>
<p>
<p>
<p>

自己的修改

1.根据移动方向挤压小球

    _angle = atanf((desPoint.y - self.position.y)/(desPoint.x - self.position.x));

    CGFloat extra = (self.currentRect.size.width * 2 / 5) * _factor;
    CGFloat radius = _currentRect.size.width/2 - extra;  
    CGFloat offset = self.currentRect.size.width / 3.6;  //设置3.6 出来的弧度最像圆形

    square.pointB = [SCCircleMath caculatePointFromAngle:_angle CirCleCenter:self.position cirCleRadius:radius1];
    square.pointC = [SCCircleMath caculatePointFromAngle:_angle + M_PI_4*2 CirCleCenter:self.position cirCleRadius:radius2];
    square.pointD = [SCCircleMath caculatePointFromAngle:_angle + M_PI_4*4 CirCleCenter:self.position cirCleRadius:radius1];
    square.pointA = [SCCircleMath caculatePointFromAngle:_angle + M_PI_4*6 CirCleCenter:self.position cirCleRadius:radius1];
    
    CGFloat sinValue = offset * sinf(_angle);
    CGFloat cosValue = offset * cosf(_angle);
    
    CGPoint c1 = CGPointMake(square.pointA.x + sinValue, square.pointA.y - cosValue);
    CGPoint c2 = CGPointMake(square.pointB.x - cosValue, square.pointB.y - sinValue);
    
    CGPoint c3 = CGPointMake(square.pointB.x + cosValue, square.pointB.y + sinValue);
    CGPoint c4 = CGPointMake(square.pointC.x + sinValue, square.pointC.y - cosValue);
    
    CGPoint c5 = CGPointMake(square.pointC.x - sinValue, square.pointC.y + cosValue);
    CGPoint c6 = CGPointMake(square.pointD.x + cosValue, square.pointD.y + sinValue);
    
    CGPoint c7 = CGPointMake(square.pointD.x - cosValue, square.pointD.y - sinValue);
    CGPoint c8 = CGPointMake(square.pointA.x - sinValue, square.pointA.y + cosValue);

    UIBezierPath* ovalPath = [UIBezierPath bezierPath];
    
    [ovalPath moveToPoint: square.pointA];
    [ovalPath addCurveToPoint:square.pointB controlPoint1:c1 controlPoint2:c2];
    [ovalPath addCurveToPoint:square.pointC controlPoint1:c3 controlPoint2:c4];
    [ovalPath addCurveToPoint:square.pointD controlPoint1:c5 controlPoint2:c6];
    [ovalPath addCurveToPoint:square.pointA controlPoint1:c7 controlPoint2:c8];
    
    [ovalPath closePath];

2.小球的移动的前半圆为半圆,后半圆为半个椭圆.

    _angle = atanf((desPoint.y - self.position.y)/(desPoint.x - self.position.x));

    CGFloat extra1 = (self.currentRect.size.width * 2 / 5) * _factor1;
    CGFloat extra2 = (self.currentRect.size.width * 2 / 5) * _factor2;
    CGFloat radius1 = _currentRect.size.width/2 - extra1;  //短边
    CGFloat radius2 = _currentRect.size.width/2 - extra2;     //长边
    CGFloat offset = self.currentRect.size.width / 3.6 - extra1 / 1.8;  //设置3.6 出来的弧度最像圆形
    ...
    square.pointB = [SCCircleMath caculatePointFromAngle:_angle CirCleCenter:self.position  cirCleRadius:radius1];
    square.pointC = [SCCircleMath caculatePointFromAngle:_angle + M_PI_4*2 CirCleCenter:self.position cirCleRadius:radius2];
    square.pointD = [SCCircleMath caculatePointFromAngle:_angle + M_PI_4*4 CirCleCenter:self.position cirCleRadius:radius1];
    square.pointA = [SCCircleMath caculatePointFromAngle:_angle + M_PI_4*6 CirCleCenter:self.position cirCleRadius:radius1];
    

图片及公式来自以下链接:
1.谈谈iOS中粘性动画以及果冻效果的实现
2.三阶贝塞尔曲线拟合1/4圆
3.KYAnimatedPageControl
4.Workout-Book-workout-tracking-app-concept

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,623评论 4 59
  • 贝塞尔曲线开发的艺术 一句话概括贝塞尔曲线:将任意一条曲线转化为精确的数学公式。 很多绘图工具中的钢笔工具,就是典...
    eclipse_xu阅读 27,528评论 38 370
  • 突然间又想到…经历,还需要一个人去做什么?那就是:一个人,爬一次山!决定了,就去做!那是回忆…多年后美好的回忆…无...
    落寞的鬼00阅读 458评论 0 0
  • 动画 StarWars.iOS:This component implements transition anim...
    willokyes阅读 355评论 0 0
  • 爱是什么 爱是慈悲 真爱是什么 真爱是瞭解 纯粹的爱呢 是只想你好 纯粹的真爱呢 舍得你受苦 永远又纯粹的真爱呢 ...
    三月品阅读 109评论 0 0