无法组合 CAKeyframe 动画以进行缩放和平移



我想同时影响图层变换的比例和平移,但只运行平移动画。这是错误的代码...

在这里,我使用 scale.y 的键路径创建缩放动画:

    self.mainImage.layer.anchorPoint = CGPointMake(0.5, 1);
    CAKeyframeAnimation *mainAnimationScale = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale.y"];
    mainAnimationScale.duration             = 0.75;
    mainAnimationScale.repeatCount          = 0;
    mainAnimationScale.removedOnCompletion  = YES;
    mainAnimationScale.autoreverses         = NO;
    mainAnimationScale.fillMode             = kCAFillModeForwards;
    mainAnimationScale.values               = [NSArray arrayWithObjects:
                                          [NSNumber numberWithFloat:1.0],
                                          [NSNumber numberWithFloat:1.0],
                                          [NSNumber numberWithFloat:0.7],
                                          [NSNumber numberWithFloat:1.0],
                                          [NSNumber numberWithFloat:0.85],
                                          [NSNumber numberWithFloat:1.0],
                                           nil];
    mainAnimationScale.keyTimes             = [NSArray arrayWithObjects:
                                          [NSNumber numberWithFloat:0],
                                          [NSNumber numberWithFloat:0.65],
                                          [NSNumber numberWithFloat:0.72],
                                          [NSNumber numberWithFloat:0.84],
                                          [NSNumber numberWithFloat:0.91],
                                          [NSNumber numberWithFloat:1],
                                           nil];

在这里,我使用翻译的键路径创建翻译动画.y:

    CAKeyframeAnimation *mainAnimationTrans = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];
    mainAnimationTrans.duration             = 0.75;
    mainAnimationTrans.repeatCount          = 0;
    mainAnimationTrans.removedOnCompletion  = YES;
    mainAnimationTrans.autoreverses         = NO;
    mainAnimationTrans.fillMode             = kCAFillModeForwards;
    mainAnimationTrans.values               = [NSArray arrayWithObjects:
                                         [NSNumber numberWithFloat:-250.0],
                                         [NSNumber numberWithFloat:-250.0],
                                         [NSNumber numberWithFloat:0],
                                           nil];
    mainAnimationTrans.keyTimes             = [NSArray arrayWithObjects:
                                          [NSNumber numberWithFloat:0],
                                          [NSNumber numberWithFloat:0.65],
                                          [NSNumber numberWithFloat:1],
                                           nil];

在这里,我将它们组合在一起并将它们应用于UIView的层:

    CAAnimationGroup *theGroup = [CAAnimationGroup animation];
    theGroup.duration = 0.75;
    theGroup.repeatCount = 0;
    theGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    theGroup.animations = [NSArray arrayWithObjects:mainAnimationTrans, mainAnimationScale, nil];
    [self.mainImage.layer addAnimation:theGroup forKey:@"layerAnimation"];

我最初尝试像这样将动画直接添加到图层中,但这也不起作用:

    [self.mainImage.layer addAnimation:mainAnimationTrans forKey:@"transform.scale.y"];
    [self.mainImage.layer addAnimation:mainAnimationTrans forKey:@"transform.translation.y"];

我已经尝试了我能想到的 keyPath 值的每个字符串,我猜这与我正在对转换的两个方面进行动画处理这一事实有关,但我认为使用该组可以解决这个问题。 唉......

完成这项工作的关键是组合转换。我不知道为什么我没有早点意识到这一点,因为它是基本的矩阵数学......我想我的同事昨天甚至提到了它。咳咳。

无论如何,我要做的动画是让一个项目下拉并在到达目的地后反弹。这是代码:

    self.mainImage.layer.anchorPoint = CGPointMake(0.3, 1.0);
    CAKeyframeAnimation *mainImageAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    mainImageAnimation.duration             = 0.75;
    mainImageAnimation.repeatCount          = 0;
    mainImageAnimation.removedOnCompletion  = NO;
    mainImageAnimation.autoreverses         = NO;
    mainImageAnimation.fillMode             = kCAFillModeForwards;
    mainImageAnimation.values               = [NSArray arrayWithObjects:
                                         [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DMakeTranslation(-8, -250, 0), 1, 1, 1)],
                                         [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DMakeTranslation(-8, 17, 0), 1, 1, 1)],
                                         [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DMakeTranslation(-8, 17, 0), 1.2, .8, 1)],
                                         [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DMakeTranslation(-8, 17, 0), .85, 1.15, 1)],
                                         [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DMakeTranslation(-8, 17, 0), 1.1, .9, 1)],
                                         [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DMakeTranslation(-8, 17, 0), 1, 1, 1)],
                                           nil];
    mainImageAnimation.keyTimes             = [NSArray arrayWithObjects:
                                          [NSNumber numberWithFloat:0],
                                          [NSNumber numberWithFloat:0.6],
                                          [NSNumber numberWithFloat:0.65],
                                          [NSNumber numberWithFloat:0.78],
                                          [NSNumber numberWithFloat:0.88],
                                          [NSNumber numberWithFloat:1],
                                           nil];
    mainImageAnimation.timingFunctions      = [NSArray arrayWithObjects:
                                         [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
                                         [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
                                         [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
                                         [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
                                         [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
                                         [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
                                           nil];
    [self.mainImage.layer addAnimation:mainImageAnimation forKey:@"transform"];

注意事项:

  • 若要实现多个转换属性,请将 CATransform3DMakeXXX 函数的结果提供给 CATransform3DXXX 函数的转换参数,从而组合各个转换。
  • 对于矩阵数学,变换的顺序很重要:你提供给矩阵的最后一件事将是应用的第一件事。就我而言,我希望在缩放之前应用翻译,因此我首先必须创建一个缩放转换并将其应用于后续的转换转换。
  • 更改图层
  • 锚点会更改图层的位置。就我而言,我需要 ancor 点是不对称的,您可以看到我如何解释平移变换中位置的变化:它的休息位置不是 0,0 而是 -8,17。

希望这有帮助!

与问题不同,但相关,我试图将两个CAKeyFrameAnimation,旋转和缩放结合起来。

CAKeyframeAnimation *wiggle = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
wiggle.values   = @[ @0.0, @-0.15, @0.0, @0.15, @-0.15, @0.0];
wiggle.keyTimes = @[ @0.0, @0.2,  @0.4, @0.6, @0.8,  @1.0];
wiggle.duration = 0.5;
CAKeyframeAnimation *resize = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
resize.duration = 0.5;
resize.values = @[@1.0, @1.5, @1.0];
resize.keyTimes = @[@0.0, @0.5, @1.0];

单独添加动画不起作用,因为只发生了旋转

[self.layer addAnimation:wiggle forKey:kAnimationKey];
[self.layer addAnimation:resize forKey:kAnimationKey];

但是当我创建一个包含两个CAKeyFrameAnimations的动画组时,它起作用了。

CAAnimationGroup *animGroup = [[CAAnimationGroup alloc] init];
animGroup.animations = @[wiggle, resize];
animGroup.duration = 0.5;
[self.layer addAnimation:animGroup forKey:kAnimationKey];

最新更新