拆分动画,除了系统的preview动画,推荐一个视频转动画的软件:Gif brewery,通过brewery我们可以一帧一帧的画面,帮助理解动画效果。
这个动画可以分为两个步骤:
1、stroke end > stroke start (渐渐显示3/4个圆弧)也就是说stroke start走到1/4,同时stroke end 绘制完一圈。
2、stroke end 等待 stroke start(圆弧渐渐消失),起点不原地不动,等待终点追赶。
中间的圆弧的是这样的,通过系统的preview动画可以看到:
思路就是把时间分割,然后装进动画组里:
- (void)loadingAnimation {
CABasicAnimation *beginStart = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
beginStart.fromValue = @0;
beginStart.toValue = @.25;
beginStart.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
beginStart.duration = self.animationDuration * 2 / 3.0;
CABasicAnimation *beginEnd = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
beginEnd.fromValue = @0;
beginEnd.toValue = @1.;
beginEnd.duration = self.animationDuration * 2 / 3.0;
上面的部分生成3/4个圆弧。
//剩下的时间用来等待
CABasicAnimation *endStart = [CABasicAnimation animation];
endStart.keyPath = @"strokeStart";
endStart.beginTime = self.animationDuration * 2 / 3.0;
endStart.duration = self.animationDuration / 3.0;
endStart.fromValue = @(0.25f);
endStart.toValue = @(1.f);
endStart.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
CABasicAnimation *endend = [CABasicAnimation animation];
endend.keyPath = @"strokeEnd";
endend.beginTime = self.animationDuration * 2 / 3.0;
endend.duration = self.animationDuration / 3.0;
endend.fromValue = @(1.f);
endend.toValue = @(1.f);
endend.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
CAAnimationGroup *strokeAniamtionGroup = [CAAnimationGroup animation];
strokeAniamtionGroup.duration = self.animationDuration;
strokeAniamtionGroup.animations = @[beginStart,beginEnd,endStart,endend];
strokeAniamtionGroup.removedOnCompletion = NO;
strokeAniamtionGroup.fillMode = kCAFillModeForwards;
strokeAniamtionGroup.repeatCount = INTMAX_MAX;
[self.loadingLayer addAnimation:strokeAniamtionGroup forKey:@"strokeAniamtionGroup"];
}
demo地址:加载动画