粘性動(dòng)畫DIY

理想效果

實(shí)際效果

思考

1.位置上的變化(spring動(dòng)畫)

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
方便用刊驴,效果一般征椒,但是不靈活渤早,功能不強(qiáng) iOS9 功能強(qiáng)大黍判,效果好,但是復(fù)雜

<p>
<p>

2.形態(tài)上的變化(變小黄痪,圓邊的弧度擠壓)

CGAffineTransform/CATransform3D
CGAffineTransformMakeScale(CGFloat sx,CGFloat sy)

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

學(xué)習(xí)

KYAnimatedPageControl(@github)
實(shí)現(xiàn)原理

三階貝塞爾曲線擬合1/4圓

帶入三個(gè)點(diǎn)計(jì)算对扶。


h = 0.552;

CGFloat extra = (self.currentRect.size.width * 2 / 5) * factor;//factor 0~1  隨時(shí)間變化

CGFloat offset = self.currentRect.size.width / 3.6;  //設(shè)置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);
關(guān)鍵幀動(dòng)畫 (對(duì)應(yīng)參數(shù)factor)
CAKeyframeAnimation

阻尼振動(dòng)






-(NSMutableArray *) springAnimationValues:(id)fromValue toValue:(id)toValue usingSpringWithDamping:(CGFloat)damping initialSpringVelocity:(CGFloat)velocity duration:(CGFloat)duration{
    
    //60個(gè)關(guān)鍵幀
    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.根據(jù)移動(dòng)方向擠壓小球

    _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;  //設(shè)置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.小球的移動(dòng)的前半圓為半圓,后半圓為半個(gè)橢圓.

    _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;     //長(zhǎng)邊
    CGFloat offset = self.currentRect.size.width / 3.6 - extra1 / 1.8;  //設(shè)置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.談?wù)刬OS中粘性動(dòng)畫以及果凍效果的實(shí)現(xiàn)
2.三階貝塞爾曲線擬合1/4圓
3.KYAnimatedPageControl
4.Workout-Book-workout-tracking-app-concept

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市父款,隨后出現(xiàn)的幾起案子溢谤,更是在濱河造成了極大的恐慌,老刑警劉巖憨攒,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件世杀,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡肝集,警方通過查閱死者的電腦和手機(jī)瞻坝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來包晰,“玉大人湿镀,你說我怎么就攤上這事炕吸》ズ叮” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵赫模,是天一觀的道長(zhǎng)树肃。 經(jīng)常有香客問我,道長(zhǎng)瀑罗,這世上最難降的妖魔是什么胸嘴? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮斩祭,結(jié)果婚禮上劣像,老公的妹妹穿的比我還像新娘。我一直安慰自己摧玫,他們只是感情好耳奕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著诬像,像睡著了一般屋群。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上坏挠,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天芍躏,我揣著相機(jī)與錄音,去河邊找鬼降狠。 笑死对竣,一個(gè)胖子當(dāng)著我的面吹牛庇楞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播否纬,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼姐刁,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了烦味?” 一聲冷哼從身側(cè)響起聂使,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎谬俄,沒想到半個(gè)月后柏靶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡溃论,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年屎蜓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钥勋。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡炬转,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出算灸,到底是詐尸還是另有隱情扼劈,我是刑警寧澤,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布菲驴,位于F島的核電站荐吵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赊瞬。R本人自食惡果不足惜先煎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望巧涧。 院中可真熱鬧薯蝎,春花似錦、人聲如沸谤绳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闷供。三九已至烟央,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間歪脏,已是汗流浹背疑俭。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留婿失,地道東北人钞艇。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓啄寡,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親哩照。 傳聞我的和親對(duì)象是個(gè)殘疾皇子挺物,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件飘弧、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,093評(píng)論 4 62
  • 貝塞爾曲線開發(fā)的藝術(shù) 一句話概括貝塞爾曲線:將任意一條曲線轉(zhuǎn)化為精確的數(shù)學(xué)公式识藤。 很多繪圖工具中的鋼筆工具,就是典...
    eclipse_xu閱讀 27,708評(píng)論 38 370
  • 突然間又想到…經(jīng)歷赶撰,還需要一個(gè)人去做什么?那就是:一個(gè)人柱彻,爬一次山豪娜!決定了,就去做哟楷!那是回憶…多年后美好的回憶…無...
    落寞的鬼00閱讀 482評(píng)論 0 0
  • 動(dòng)畫 StarWars.iOS:This component implements transition anim...
    willokyes閱讀 378評(píng)論 0 0
  • 愛是什么 愛是慈悲 真愛是什么 真愛是瞭解 純粹的愛呢 是只想你好 純粹的真愛呢 舍得你受苦 永遠(yuǎn)又純粹的真愛呢 ...
    三月品閱讀 122評(píng)論 0 0