理想效果
實(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
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