6

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

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

}

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

4

3 回答 3

10

可以将 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);

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

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

    CGContextSaveGState(context);
    CGContextConcatCTM(context, affine);
    [layer renderInContext:context];
    CGContextRestoreGState(context);
于 2013-08-26T15:32:08.270 回答
3

当然。如果您在 Xcode 文档中搜索 CGAffineTransform,您会找到标题为“CGAffineTransform Reference”的一章。在那一章中有一节叫做“功能”。它包括等效于 CATransform3DScale (CGAffineTransformScale) 和 CATransform3DRotate (CGAffineTransformRotate) 的函数。

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

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

于 2012-05-08T17:24:52.307 回答
0

您可以使用CATransform3DGetAffineTransform将 CATransform3d 转换为 CGAffineTransform。

let scaleTransform = CATransform3DMakeScale( 0.8, 0.8, 1)
imageview.transform = CATransform3DGetAffineTransform(scaleTransform)
于 2021-03-23T11:32:34.570 回答