从CATransform3D到CGAffineTransform

Abr*_*odj 5 core-animation core-graphics

我正在使用以下函数将脉冲效果应用于视图

- (void)pulse {

    CATransform3D trasform = CATransform3DScale(self.layer.transform, 1.15, 1.15, 1);
    trasform = CATransform3DRotate(trasform, angle, 0, 0, 0);

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
    animation.toValue = [NSValue valueWithCATransform3D:trasform];
    animation.autoreverses = YES;
    animation.duration = 0.3;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    animation.repeatCount = 2;
    [self.layer addAnimation:animation forKey:@"pulseAnimation"];

}
Run Code Online (Sandbox Code Playgroud)

我想使用CGAffineTransform self.transform而不是CATransform3D self.layer.transform获得相同的结果.这可能吗?

Kev*_*ner 8

可以将a转换CATransform3D为a CGAffineTransform,但是你会丢失一些功能.我发现将图层及其祖先的聚合转换转换为a是有用的,CGAffineTransform所以我可以用Core Graphics渲染它.限制是:

  • 您的输入将在XY平面中视为平坦
  • 您的输出也将在XY平面中视为平坦
  • 透视/透视.m34将被中和

如果这听起来没问题:

    // m13, m23, m33, m43 are not important since the destination is a flat XY plane.
    // m31, m32 are not important since they would multiply with z = 0.
    // m34 is zeroed here, so that neutralizes foreshortening. We can't avoid that.
    // m44 is implicitly 1 as CGAffineTransform's m33.
    CATransform3D fullTransform = <your 3D transform>
    CGAffineTransform affine = CGAffineTransformMake(fullTransform.m11, fullTransform.m12, fullTransform.m21, fullTransform.m22, fullTransform.m41, fullTransform.m42);
Run Code Online (Sandbox Code Playgroud)

您将首先想要在3D变换中完成所有工作,例如通过连接您的超级层,然后最终将聚合转换CATransform3DCGAffineTransform.鉴于层开始时是平的并且渲染到平坦目标上,我发现这非常合适,因为我的3D旋转变成了2D剪切.我还发现牺牲透视可以接受.没有办法解决这个问题,因为仿射变换必须保留平行线.

例如,要使用Core Graphics渲染3D变换图层,您可以连接变换(尊重锚点!),然后转换为仿射,最后:

    CGContextSaveGState(context);
    CGContextConcatCTM(context, affine);
    [layer renderInContext:context];
    CGContextRestoreGState(context);
Run Code Online (Sandbox Code Playgroud)


Dun*_*n C 3

当然。如果您在 Xcode 文档中搜索 CGAffineTransform,您将找到标题为“CGAffineTransform Reference”的章节。该章中有一个名为“函数”的部分。它包括与 CATransform3DScale (CGAffineTransformScale ) 和 CATransform3DRotate (CGAffineTransformRotate) 等效的函数。

请注意,您对 CATransform3DRotate 的调用实际上没有意义。您需要绕一个轴旋转,并且为所有 3 个轴传递 0。通常您希望使用 CATransform3DRotate(trasform, angle, 0, 0, 1.0 ) 绕 Z 轴旋转。引用文档:

如果向量的长度为零,则行为未定义。

  • 你确实没说清楚。我猜测,CGAffineTransform 用于视图,CATransform3D 用于图层,您想知道如何执行基于视图的动画,指定不同的计时函数。为此,您需要使用 animateWithDuration:delay:options:animations:completion: UIView 类方法。options 参数包括 UIViewAnimationOptionCurveEaseInOut、UIViewAnimationOptionCurveLinear 等值。只需指定所需的选项,然后更改动画块中的变换即可。 (2认同)