3

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

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

    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];

在这里,我使用 translation.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 值的字符串,我猜这与我正在为变换的两个方面设置动画这一事实有关,但我认为使用该组可以解决这个问题。唉...

4

2 回答 2

2

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

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

    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函数的 transform 参数来实现多个变换属性,从而组合各个变换。
  • 使用矩阵数学,转换的顺序很重要:您输入矩阵的最后一件事将是应用的第一件事。在我的情况下,我希望在缩放之前应用平移,因此我首先必须创建一个缩放变换并将其应用于后续的平移变换。
  • 更改图层的锚点会更改图层的位置。在我的例子中,我需要 ancor 点是不对称的,你可以看到我如何解释平移变换中的位置变化:它的静止位置不是 0,0 而是 -8,17。

希望这可以帮助!

于 2012-05-25T15:04:44.733 回答
0

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

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];
于 2014-05-12T18:35:24.510 回答