如何在IOS中同时创建月亮绕地球自转的CAAnimation效果?
How to create a CAAnimation effect like moon rotates around the earth and rotates by itself at the same time in IOS?
我知道在IOS中制作月亮绕地球转的效果很简单。假设月亮是一个 CALayer 对象,只需将这个对象的 anchorPoint 改为地球,它就会围绕地球旋转。但是如何创造同时自转的月亮呢?由于月亮只能有一个锚点,看来我不能再让这个 CALayer 对象自行旋转了。你们有什么感想?谢谢。
您可以使 "moon" 围绕一个点旋转,方法是沿贝塞尔曲线路径设置动画,同时设置旋转变换动画。这是一个简单的例子,
@interface ViewController ()
@property (strong,nonatomic) UIButton *moon;
@property (strong,nonatomic) UIBezierPath *circlePath;
@end
@implementation ViewController
-(void)viewDidLoad {
self.moon = [UIButton buttonWithType:UIButtonTypeInfoDark];
[self.moon addTarget:self action:@selector(clickedCircleButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.moon];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
CGRect circleRect = CGRectMake(60,100,200,200);
self.circlePath = [UIBezierPath bezierPathWithOvalInRect:circleRect];
self.moon.center = CGPointMake(circleRect.origin.x + circleRect.size.width, circleRect.origin.y + circleRect.size.height/2.0);
}
- (void)clickedCircleButton:(UIButton *)sender {
CAKeyframeAnimation *orbit = [CAKeyframeAnimation animationWithKeyPath:@"position"];
orbit.path = self.circlePath.CGPath;
orbit.calculationMode = kCAAnimationPaced;
orbit.duration = 4.0;
orbit.repeatCount = CGFLOAT_MAX;
[self.moon.layer addAnimation:orbit forKey:@"circleAnimation"];
CABasicAnimation *fullRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
fullRotation.fromValue = 0;
fullRotation.byValue = @(2.0*M_PI);
fullRotation.duration = 4.0;
fullRotation.repeatCount = CGFLOAT_MAX;
[self.moon.layer addAnimation:fullRotation forKey:@"Rotate"];
}
这些特定的值将导致 "moon" 像地球的月亮一样将同一个面朝向中心。
使用两层。
一个是从地球到月球的无形"arm"。它围绕其锚点(即地球的中心)进行旋转变换。这导致 "arm" 尽头的月亮围绕地球旋转。
另一个是月亮。它是 "arm" 的子层,位于手臂的末端。如果你想让它独立旋转,围绕它的个锚点旋转,也就是它自己的中心。
(但是请注意,真实的月球不会这样做。对于真实的月球,"arm" 就足够了,因为真实的月球自转与它自己围绕地球的公转同步 - 所以我们总是看到同一张月亮的脸。)
我知道在IOS中制作月亮绕地球转的效果很简单。假设月亮是一个 CALayer 对象,只需将这个对象的 anchorPoint 改为地球,它就会围绕地球旋转。但是如何创造同时自转的月亮呢?由于月亮只能有一个锚点,看来我不能再让这个 CALayer 对象自行旋转了。你们有什么感想?谢谢。
您可以使 "moon" 围绕一个点旋转,方法是沿贝塞尔曲线路径设置动画,同时设置旋转变换动画。这是一个简单的例子,
@interface ViewController ()
@property (strong,nonatomic) UIButton *moon;
@property (strong,nonatomic) UIBezierPath *circlePath;
@end
@implementation ViewController
-(void)viewDidLoad {
self.moon = [UIButton buttonWithType:UIButtonTypeInfoDark];
[self.moon addTarget:self action:@selector(clickedCircleButton:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.moon];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
CGRect circleRect = CGRectMake(60,100,200,200);
self.circlePath = [UIBezierPath bezierPathWithOvalInRect:circleRect];
self.moon.center = CGPointMake(circleRect.origin.x + circleRect.size.width, circleRect.origin.y + circleRect.size.height/2.0);
}
- (void)clickedCircleButton:(UIButton *)sender {
CAKeyframeAnimation *orbit = [CAKeyframeAnimation animationWithKeyPath:@"position"];
orbit.path = self.circlePath.CGPath;
orbit.calculationMode = kCAAnimationPaced;
orbit.duration = 4.0;
orbit.repeatCount = CGFLOAT_MAX;
[self.moon.layer addAnimation:orbit forKey:@"circleAnimation"];
CABasicAnimation *fullRotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
fullRotation.fromValue = 0;
fullRotation.byValue = @(2.0*M_PI);
fullRotation.duration = 4.0;
fullRotation.repeatCount = CGFLOAT_MAX;
[self.moon.layer addAnimation:fullRotation forKey:@"Rotate"];
}
这些特定的值将导致 "moon" 像地球的月亮一样将同一个面朝向中心。
使用两层。
一个是从地球到月球的无形"arm"。它围绕其锚点(即地球的中心)进行旋转变换。这导致 "arm" 尽头的月亮围绕地球旋转。
另一个是月亮。它是 "arm" 的子层,位于手臂的末端。如果你想让它独立旋转,围绕它的个锚点旋转,也就是它自己的中心。
(但是请注意,真实的月球不会这样做。对于真实的月球,"arm" 就足够了,因为真实的月球自转与它自己围绕地球的公转同步 - 所以我们总是看到同一张月亮的脸。)