方向改变期间平滑的方面变化

时间:2012-08-18 18:52:57

标签: iphone objective-c ios opengl-es-2.0 aspect-ratio

当iPhone方向的屏幕发生变化时,我将3D渲染的投影矩阵调整为新的方位值。但是,在willRotateToInterfaceOrientationdidRotateFromInterfaceOrientation中执行此操作会导致在转换期间宽高比错误,因为在动画开始时,屏幕大小仍然与以前相同并且更改为旋转时逐渐出现新界限。因此,我希望用于3D投影矩阵的方位值也会逐渐变化。为此,我在willAnimateRotationToInterfaceOrientation中检索旋转动画的开始时间和持续时间:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    _aspect.isChanging = YES;
    _aspect.startedChanging = [[NSDate date] retain];
    _aspect.changeDuration = duration;
    _aspect.oldValue = self.renderer.aspect;
    _aspect.currentValue = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
}

请注意,视图边界大小已设置为在动画后有效的新值。

然后,在update中,我执行以下操作:

- (void)update
{
    if (_aspect.isChanging) {
        float f = MIN(1, [[NSDate date] timeIntervalSinceDate:_aspect.startedChanging] / _aspect.changeDuration);
        self.renderer.aspect = _aspect.oldValue * (1-f) + _aspect.currentValue * f;
    } else {
        self.renderer.aspect = _aspect.currentValue;
    }
    [self.renderer update];
}

这已经很好用,但渲染方面的变化与实际的方面变化不匹配,这是因为我是线性插值的。因此,我尝试通过在问题上抛出数学函数来匹配实际方面变化的缓和:我能得到的最好结果是添加以下行:

f = 0.5f - 0.5f*cosf(f*M_PI); 

这导致在旋转期间几乎没有可见的图像拉伸,但是如果仔细观察,它之间似乎仍然有点无法比拟。我想,最终用户不会注意到它,但我在这里问是否有更好的解决方案,所以这些是我的问题:

  • 旋转变化动画期间用于宽高比变化的实际缓动函数是什么?
  • 有没有办法获得在方向更改动画期间显示的视图的实际宽度和高度?这将允许我直接检索中间方面。

1 个答案:

答案 0 :(得分:3)

在第一个项目符号点上,您可以使用CAMediaTimingFunction(可能带有kCAMediaTimingFunctionEaseInEaseOut)来获取定义过渡的曲线的控制点。然后使用三次贝塞尔曲线公式。

在第二个要点上,您可以使用[[view layer] presentationLayer]获取该视图CALayer的版本,并根据当前状态应用所有当前动画。因此,如果你检查它的尺寸,你应该获得当前的值 - 我想如果你对CADisplayLink回调采取行动,那么你最多只能落后一帧。