iOS 动画四:transform 动画

一、iOS transform 动画

@property(nonatomic) CGAffineTransform transform;  *// view 的属性*
@property CATransform3D transform; *// layer 的属性*
  • view.transform:一般是 View 的旋转,拉伸移动等属性,是二维的,通常使用都是前缀 CGAffineTransform 的类。
  • view.layer.transform:可以在 3D 模式下面的变化,通常使用的都是前缀为 CATransform3D 的类。

两者的区别就是在 二维和 三维的区别,是用 CGAffineTransform 和 CATransform3D 的区别。

transform 几个常用的函数:

/// 用来连接两个变换效果并返回。返回的t = t1 * t2
CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2)
 
/// 矩阵初始值。[ 1 0 0 1 0 0 ]
CGAffineTransformIdentity
 
/// 自定义矩阵变换,需要掌握矩阵变换的知识才知道怎么用。参照上面推荐的原理链接
CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty)
 
/// 旋转视图。传入参数为 角度 * (M_PI / 180)。等同于 CGAffineTransformRotate(self.transform, angle)
CGAffineTransformMakeRotation(CGFloat angle)
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
 
/// 缩放视图。等同于CGAffineTransformScale(self.transform, sx, sy)
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
 
/// 缩放视图。等同于CGAffineTransformTranslate(self.transform, tx, ty)
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)

1、平移

//平移
[UIView animateWithDuration:0.5 animations:^{
//使用Make,它是相对于最原始的位置做的形变.
//self.imageV.transform = CGAffineTransformMakeTranslation(0, -100);
//相对于上一次做形变.
self.imageV.transform = CGAffineTransformTranslate(self.imageV.transform, 0, -100);
}];
/* Return a transform which translates by `(tx, ty)':
         t' = [ 1 0 0 1 tx ty ] */
public init(translationX tx: CGFloat, y ty: CGFloat)

经过坐标变换,可以得到

x' = x + tx
y' = y + ty

2、旋转

[UIView animateWithDuration:0.5 animations:^{

//旋转(旋转的度数, 是一个弧度)
//self.imageV.transform = CGAffineTransformMakeRotation(M_PI_4);

self.imageV.transform = CGAffineTransformRotate(self.imageV.transform, M_PI_4);

}];
/* Return a transform which scales by `(sx, sy)':
         t' = [ sx 0 0 sy 0 0 ] */
public init(scaleX sx: CGFloat, y sy: CGFloat)

经过坐标变换,可以得到

x' = x * sx
y' = y * sy

3、缩放

[UIView animateWithDuration:0.5 animations:^{
//缩放
//self.imageV.transform = CGAffineTransformMakeScale(0.5, 0.5);
  self.imageV.transform = CGAffineTransformScale(self.imageV.transform, 0.8, 0.8);
}];
/* Return a transform which rotates by `angle' radians:
         t' = [ cos(angle) sin(angle) -sin(angle) cos(angle) 0 0 ] */
public init(rotationAngle angle: CGFloat)

这里入参是一个弧度值,角度 x 转换为弧度

angle

angle = x*Double.pi/180

假设 v 点的坐标是(x,y),那么可以推导得到 v′ 点的坐标(x′ ,y′ )(设原点到 v 的距离是 r,原点到 v 点的向量与 x 轴的夹角是 ϕ )

x = rcosϕ, y = rsinϕ
x′ = rcos(θ+ϕ), y′= rsin(θ+ϕ)

通过三角函数展开得到

x′ = rcosθcosϕ − rsinθsinϕ
y′ = rsinθcosϕ + rcosθsinϕ

带入 x 和 y 表达式得到

x′ = xcosθ − ysinθ
y′ = xsinθ + ycosθ

写成矩阵的形式即:

二、CGAffineTransform 仿射变换

CGAffineTransform 结构体定义如下:

struct CGAffineTransform {
  CGFloat a, b, c, d;
  CGFloat tx, ty;
};

假设 b = c = 0
那么可以有下面两个情况:

a表示x水平方向的缩放,tx表示x水平方向的偏移
d表示y垂直方向的缩放,ty表示y垂直方向的偏移
如果b和c不为零的话,那么视图肯定发生了旋转

放射矩阵一个常用的情形就是根据用户的手势来相应的改变视图的变换,如:

UIPanGestureRecognizer 位移
UIPinchGestureRecognizer 缩放
UIRotationGestureRecognizer 旋转

苹果官方建议,如果我们想对对象进行缩放和旋转操作,我们不用直接创建 affine transforms,我们可以调用 CGContextTranslateCTM,CGContextScaleCTM, CGContextRotateCTM 这样的方法来实现我们想要的旋转、缩放、移动的效果。

Note that you do not typically need to create affine transforms directly. If you want only to draw an object that is scaled or rotated, for example, it is not necessary to construct an affine transform to do so. The most direct way to manipulate your drawing—whether by movement, scaling, or rotation—is to call the functions CGContextTranslateCTM,CGContextScaleCTM, orCGContextRotateCTM, respectively. You should generally only create an affine transform if you want to reuse it later.

小结:想想我们大学时候学习的高数、线性代数、概率论,知道它们在现实中有什么用处了吧!计算机问题归根到底是数学的问题。数学没学好的同学,努力补习功课吧,欠的债早晚要还的。接下来我得好好去学学数学了,(⊙﹏⊙) …

2018.06.21 夜
上海 虹桥

附: demo下载地址

参考链接:

  1. iOS 动画 —— transform - 简书
  2. iOS 开发之动画篇 - Transform和KeyFrame动画
  3. CGAffineTransform 放射变换 - CSDN博客
  4. CGAffineTransform二维视图旋转、缩放、平移变换详解 - 掘金
  5. CGAffineTransform - 简书
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,245评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,749评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,960评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,575评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,668评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,670评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,664评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,422评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,864评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,178评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,340评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,015评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,646评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,265评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,494评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,261评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,206评论 2 352

推荐阅读更多精彩内容