使用下面的代码,既可以获得某个CATransform3DMake...()方法获取的变换的透视投影效果。
最后,将该函数的返回值赋给某个UIView或者其子类对象的layer属性的transform属性即可。
// 实现带透视投影缩放效果的三维变换。
CATransform3D get3DPerspectiveTransform(CATransform3D t, CGPoint center, float disZ)
{
/**************************************************************
* CATransform3DConcat(CATransform3D a, CATransform3D b)的含义
* 是先进行a变换,再进行b变换。b变换在a变换的基础上进行。
**************************************************************/
// 将某个view移动到坐标系原点的变换矩阵。
CATransform3D transToOrigin = CATransform3DMakeTranslation(-center.x, -center.y, 0);
// 将view移动回初始位置的变换矩阵。
CATransform3D transBack = CATransform3DMakeTranslation(center.x, center.y, 0);
// 计算透视缩放矩阵。
// 透视投影的m34即表示透视缩放系数。这个值越小,则透视效果越明显(即越近越大,越远越小)。
CATransform3D scale = CATransform3DIdentity;
// 注意这里是-1,从而保证从坐标轴正方向向负方向看去,逆时针旋转为正。
scale.m34 = -1.0f/disZ;
// 获取完整的透视变换矩阵。
CATransform3D perspTrans = CATransform3DConcat(CATransform3DConcat(transToOrigin, scale), transBack);
// 为iOS的标准正投影添加透视投影变换效果。
CATransform3D result = CATransform3DConcat(t, perspTrans);
return result;
}
例:在某个ViewController的viewDidLoad中,初始化一个计时器,每1/60秒调用一次:
[NSTimer scheduledTimerWithTimeInterval:1/60
target:self
selector:@selector(callFuncPerFrame:)
userInfo:nil
repeats:YES];
#pragma mark - 定时器回调方法,实现动态效果。
- (void)callFuncPerFrame:(NSTimer *)timer
{
static float angle = 0.0f;
CATransform3D t = get3DPerspectiveTransform(CATransform3DMakeRotation(angle, 0, 1, 0),
CGPointZero,
500);
[imgView.layer setTransform:t];
angle += 0.01f;
angle = (angle == 360.0f ? 0.0f : angle);
}
最终效果如下图所示: