我正在尝试做的似乎应该很简单:我创建了一张旧留声机唱片的 2D 自上而下视图。我想在它的 X 轴上旋转它(把它放回去),然后围绕它的 Z 轴旋转它。
我在这里阅读了所有包含 CATransform3D 的问题,我阅读了 Steve Baker 的“矩阵可以成为你的朋友”文章以及 Bill Dudney 的书“Mac OS X 和 iPhone 的核心动画”,我认为 Brad Larson 的“ 3-D Rotation without a trackball”具有所有正确的代码,但由于他允许用户调整所有三个轴,我很难将他的代码缩小到我认为只是一维的(旋转的 z 轴)。
这是我正在测试的图像,并不是说细节对问题很重要:
我以通常的方式将其显示在屏幕上:(在 UIView 的子类中)
- (void)awakeFromNib
{
UIImage *recordImage = [UIImage imageNamed:@"3DgoldRecord"];
if (recordImage) {
recordLayer = [CALayer layer];
[recordLayer setFrame:CGRectMake(0.0, 0.0, 1024, 1024)];
[recordLayer setContents:(id)[[UIImage imageNamed:@"3DgoldRecord"] CGImage]];
[self.layer addSublayer:recordLayer];
}
}
这是第一次测试,只是在屏幕上显示 ;-)
然后,为了“放回去”,我应用一个变换来绕图层的 X 轴旋转,在将图层的内容设置为图像之后和添加子图层之前插入此代码:
CATransform3D myRotationTransform =
CATransform3DRotate(recordLayer.transform,
(M_PI_2 * 0.85), //experiment with flatness
1.0, // rotate only across the x-axis
0.0, // no y-axis transform
0.0); // no z-axis transform
recordLayer.transform = myRotationTransform;
这按预期工作:记录很好地放回。
对于下一步,导致记录旋转,我将此动画绑定到 touchesEnded 事件,尽管一旦退出测试/学习阶段,此旋转将不受用户控制:
CATransform3D currentTransform = recordLayer.transform; // to come back to at the end
CATransform3D myRotationTransform =
CATransform3DRotate(currentTransform,
1.0, // go all the way around once
(M_PI_2 * 0.85), // x-axis change
1.00, // y-axis change ?
0.0); // z-axis change ?
recordLayer.transform = myRotationTransform;
CABasicAnimation *myAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
myAnimation.duration = 5.0;
myAnimation.fromValue = [NSNumber numberWithFloat:0.0];
myAnimation.toValue = [NSNumber numberWithFloat:M_PI * 2.0];
myAnimation.delegate = self;
[recordLayer addAnimation:myAnimation forKey:@"transform.rotation"];
所以我很确定我挂断的是 CATransform3DRotate 调用中的向量(相信我:我一直在尝试对该向量进行简单的更改以观察变化......现在列出的只是最后一次更改我试过)。据我了解,变换中x、y和z的值本质上是动画期间传入的值的百分比,范围从fromValue到toValue。
如果我在正确的轨道上理解这一点,是否可以在一次转换中表达这一点?或者我是否必须为每个有效的动画帧围绕 z 轴稍微旋转原始直立图像,然后通过 x 轴旋转放置结果?我看到一个关于组合变换的问题/答案,但那是一个比例变换,然后是一个旋转变换。我已经搞砸了变换变换,但没有做我认为我应该得到的事情(即将一个变换的结果传递给下一个变换参数似乎只是完全执行一个然后为另一个设置动画)。