iOS动效-利用CATransform3D实现翻页动画效果

从iOS开发已发出一段时间了,之前一直无暇工作,几乎很少发时空写有物来对协调控制的技术拓展一下总结,现在沉思,有些后悔,因为之前以遇到问题的下要上新技巧之时段都是以翻译看他人的博客或者查看苹果之法定文档,一直是一个于行业内的“价值消耗者”,对是,我也做了深刻的反省,现在下定狠心,以自己微小之能力来贡献一些物,也许会指向人家有助,希望自己不再是相同称为“价值消耗者”或是“观望者”,转变为同样号称“价值贡献者”或是“价值传递者”,在这向那些穿梭朝着互联网贡献的众人致以崇高敬意!

“iOS动效”

希冀为CityGuideApp,来自UI中国,特此声明

在App爆发式增长的一代,移动App的竞争就自不过的量跟技术稳定性的竞争,上升到用户体验和服务等重新胜界上之竞争,越来越多的营业所开始更有“人文关怀”地关注App上之用户体验,合理可行的动效是构建可以用户体验不可缺失失的同等围,恰当好处的动效可以使用户以App中获取明显的互动反馈、愉悦的动感受与当千头万绪现象下对迷失方向等过剩功利,这吗是胡咱们而讲话动效的原因。

从今技术层面达到的话,Apple在iOS平台达成提供了供开发者使用的洋洋处理器图形技术,这里包括了UIKit框架内之UIView动画技术、Graphics
& Animation框架内的2D Drawing、3D
Drawing技术、CoreAnimation技术等。这些丰富的图纸和动画片技术框架是iOS平台上贯彻各种华丽动效的水源,第三在为发出诸如facebook的Pop动画引擎,甚至有些App会动用OpenGL、SpriteKit、Metal等游艺引擎来撰写复杂的卡通片效果,Apple也在WWDC
2015备受显得了OX
10.11和iOS9惨遭,使用Metal来更写系统级别的动效,从而升级用户体验,我们发理由相信在未来,越来越多之App开发会大方动合理的动效技术来完善App的用户体验。

废话了这么多,下面开始讲点实在的技能东西,这次来贯彻以下利用CATransform3D来举行一个近似FilpBoard折纸翻页。

github-DEMO地址

成效如下:

雨滴的iCon图片是为此sketch做的,有接触丑,大家包涵!

演示git

viewDebugging的因素做

率先来梳理一下思路:

1.图本身在UIView上,UIView上布局两只UIImageView,分为左右点儿止,每个UIImageView进行了圆角mask遮罩,UIImageView的image属性为割的一半image。

2.UIView加Pan手势,手势教右边的UIImageView做transform属性动画,transform属性为CATransform3D,做顺Y轴的CATransform3DRotation仿射变换。

3.于不停变更transform的性质之又,判断右边UIImageVIew是否旋转程度,使得左右点儿限的图纸及出示渐变阴影。

4.转超过一半的时刻,将右侧边的UIImageVIew的image图片,替换成原来图片加上阴影左右翻转之图,实现转后背景图是混淆的背景。

以上就简的思绪,这之中比较基本的即使是右边的UIImageVIew如何举行Y轴的rotation旋转,并且如何贯彻带有左边小右边挺之检效果。

采取transform属性来开仿射变换,我们要清楚transform的面目是呀,iOS中分为2D同3D的仿射变换矩阵。

3D仿射变换矩阵

当iOS中,layer层的岗位别是由此如图所示的仿射变换矩阵计算来表示的,计算机图形学着,三维坐标系可以描述三维空间的职,iOS平台为非异,在CoreAnimation框架中,layer层的tranform属性可以是CATransform3D类型的季维仿射变换矩阵,并且提供预置好的拓盘、变形的仿射变换矩阵,这时候,我们唯有需要通过取得我们想只要之卡通片效果就后用的CATransform3D的transform,再长CAAnimation的增援,就足以做出优雅的补间动画。

对于地方的板栗,我们的中坚组成部分就是是,右边的UIImageView根据pan手势而连变更之transform属性,核心代码如下:

-(CATransform3D)getTransForm3DWithAngle:(CGFloat)angle{

CATransform3D transform
=CATransform3DIdentity;//获取一个正规默认的CATransform3D仿射变换矩阵

transform.m34=4.5/-2000;//透视效果

transform=CATransform3DRotate(transform,angle,0,1,0);//获取旋转angle角度后的rotation矩阵。

return transform;

}

方最要害的凡m34这个特性,CATransform3DRotate赢得之转如果前并的transform不支持透视,那以x、y轴上召开旋转是特生frame放大缩小的变通,我们得之是以打转的下如果叫离视角近的地方加大,离视角远之地方压缩,就是所谓的视差来形成3D底效益。

struct CATransform3D

{

CGFloat m11, m12, m13, m14;

CGFloat m21, m22, m23, m24;

CGFloat m31, m32, m33, m34;

CGFloat m41, m42, m43, m44;

};

//这是CATransform3D基本的结构体

矩阵乘法计算

我们可以看出m34实际上影响了z轴方向的translation,m34= -1/D, 
默认值是0,我们要尽可能的让m34者值尽可能小,但还要不能不发强烈的远小近百倍的效能。

以上我们举行了冲角度(angle)获得transform的API,那么我们就是足以拿当UIView上的pan手势转化为angle,获取实时的transform属性,来开属性动画,在自己之DEMO里独自是只是的安装新的transform属性,如果要动画更细致,可以用CAAnimation或者是CADisplayLink进行各秒60轴的刷新,使得形变更加细致。

CGPoint location = [pan
locationInView:self];//获取在View中的location

if(pan.state==UIGestureRecognizerStateBegan) {

self.initialLocation= location.x;

}//在手势开始之时光,使用性质记录手势在View上的X坐标

if([[self.rightImageView.layervalueForKeyPath:@”transform.rotation.y”]floatValue]
>
-M_PI_2&&([[self.rightImageView.layervalueForKeyPath:@”transform.rotation.x”]floatValue]
!=0)) {

self.rightBackView.alpha=1;//此时让模糊翻转的背景图片显示出

self.rightShadowLayer.opacity=0;//使得右边的UIImageView的影遮罩隐藏

CGFloat opacity =
(location.x-self.initialLocation)/(CGRectGetWidth(self.bounds)-self.initialLocation);//根据初始化距离及这location的大小除以相对(宽度-初始x坐标)等于一个而长的手势滑动程度,可一直当调节阴影的透明度

self.leftShadowLayer.opacity=fabs(opacity)*0.5;

}//在右边UIImageView的rotation.y>-M_PI_2(说明当召开顺时针旋转)和rotation.x!=0(说明相对于原职位,x轴做了转,此时于右边边翻转到左),至于缘何是这般的参数判断,需要了解layer层的坐标系与业内空间坐标系的差距。

else
if(([[self.rightImageView.layervalueForKeyPath:@”transform.rotation.y”]floatValue]
>
-M_PI_2)&&([[self.rightImageView.layervalueForKeyPath:@”transform.rotation.y”]floatValue]<0)&&([[self.rightImageView.layervalueForKeyPath:@”transform.rotation.x”]floatValue]
==0))

{

self.rightBackView.alpha=0;//此时右边的UIImageView已经旋转但是还没转动至左,使得背景模糊左右倒之图形的透明度为0

CGFloatopacity =
(location.x-self.initialLocation)/(CGRectGetWidth(self.bounds)-self.initialLocation);

//self.rightShadowLayer.opacity = 0 ;

self.rightShadowLayer.opacity=fabs(opacity)*0.5;

self.leftShadowLayer.opacity=fabs(opacity)*0.5;

}

if([selfisLocation:locationinView:self]) {

CGFloat conversioFactor
=M_PI/(CGRectGetWidth(self.bounds)-self.initialLocation);

self.rightImageView.layer.transform=
[selfgetTransForm3DWithAngle:(location.x-self.initialLocation)*conversioFactor];//在手势还在view的限制外,通过location获得待旋转的角度的比重,然后调用写好之API来取transform

}

else{pan.enabled=NO;

pan.enabled=YES;

}

每当得pan手势的handle之后,我们用解决一下,右边UIImageView的沿X=0的Y轴进行盘的题材。这时候我们需要改右边UIImageView的Layer的Anchor
Points。

anchoriPoint说明

关于anchoriPoint对于layer层在父坐标系与本人坐标系的熏陶,上图已经会清楚可辨了,再次不多废话。

self.rightImageView.layer.anchorPoint=CGPointMake(0,0.5);//需要沿X=0的y轴旋转,需要让anchorPoint=(0,0.5)

self.rightImageView.frame=CGRectMake(CGRectGetMidX(self.bounds),0,CGRectGetWidth(self.bounds)/2,CGRectGetHeight(self.bounds));
//修改完anchorPoint之后会挑起layer的position的变更,所以需要还修改frame使得layer在不利的职务及。注意修改的先后顺序,frame实际是没价值的,是依据position和anchorPoint算出来的,这同一点大家需要周知

总结:

1.亟待是安装仿射变换的transform,这里牵扯到旋转变换的坐标轴是怎样设置。

2.要小心pan手势handle中之折算问题,如何将手势滑动程度转换为转角度,这个没什么特别要留意,只能通过经历积累。

3.待专注旋转的视差设置,需要了解3D仿射变换的矩阵运算,抓住本质问题。

4.需要调剂诸如左右图形的圆角mask设置,在DEMO源码中,大家可以找到以UIBezierPath做的mask遮罩layer,能够设置圆角之个数与位置,还有阴影的调试,旋转至得角度后底模糊背景,从而模仿真实的大体现象,关注这些细节才会完善用户体验。

如上所述,要做出这么的相互类型的动效,需要关爱iOS平台下关于动画的基本知识和周转规律。苹果官方提供强大的文档Library供大家读,在这个,我为特是望大家不用害怕英文文档,阅读官方文档是同等种进阶的飞速道。

下次,我将显示一个应用pop动画引擎库实现的卡片式设计的卡通,这点同等是指望能够跟更多的UE设计人员关系,因为pop动画简化了开发成本,但针对计划要求还强,需要安装有符合动效美学的动画参数,而且相当facebook为苹果之Quartz
Composer功能提供的origami插件,pop动画实现的userinterface会更加有“情怀”。同时,个人觉得,App的支出,无论对于开发者或是产品或UE等等相关人口来讲,都是一个更是专业化的工作,而这些可以之家伙是故来增长我们的工作效率,但为就是工具,代码也是,而真发出价的凡咱们共同指向美好(审美)、用户体验、满足合理诉求的一致的言情。

非常感谢大家!希望大家共同进步!

有关资料:

Apple Developer Library
:Graphics&Animation