Core Animation實戰五(變換)

仿射變換
/* Translate `t' by `(tx, ty)' and return the result:
t' = [ 1 0 0 1 tx ty ] * t */
CG_EXTERN CGAffineTransform CGAffineTransformTranslate(CGAffineTransform t,
CGFloat tx, CGFloat ty) CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
/* Scale `t' by `(sx, sy)' and return the result:
t' = [ sx 0 0 sy 0 0 ] * t */
CG_EXTERN CGAffineTransform CGAffineTransformScale(CGAffineTransform t,
CGFloat sx, CGFloat sy) CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
/* Rotate `t' by `angle' radians and return the result:
t' = [ cos(angle) sin(angle) -sin(angle) cos(angle) 0 0 ] * t */
CG_EXTERN CGAffineTransform CGAffineTransformRotate(CGAffineTransform t,
CGFloat angle) CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
DEMO:
//
// CGAffineTransformViewController.m
// LayerStudyDemo
//
// Created by apple on 2017/9/30.
// Copyright © 2017年 ZY. All rights reserved.
//
#import "CGAffineTransformViewController.h"
@interface CGAffineTransformViewController ()
@property (weak, nonatomic) IBOutlet UITextView *layerTextView;
@end
@implementation CGAffineTransformViewController
- (void)viewDidLoad {
[super viewDidLoad];
//CGAffineTransform 建立初始化
CGAffineTransform transform = CGAffineTransformIdentity;
//縮放
transform = CGAffineTransformScale(transform, 0.6, 0.6);
//旋轉
transform = CGAffineTransformRotate(transform, M_PI / 180.0 * 30.0);
//位移變化
transform = CGAffineTransformTranslate(transform, 20, 100);
//應用到layer
self.layerTextView.layer.affineTransform = transform;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
3D仿射變換
根據名字我們可以知道,3D仿射變化與仿射變化的區別在於3D是三維矩陣的變換,有了Z軸變化。
//
// ThreeDTransViewController.m
// LayerStudyDemo
//
// Created by apple on 2017/10/9.
// Copyright © 2017年 ZY. All rights reserved.
//
#import "ThreeDTransViewController.h"
@interface ThreeDTransViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imgView;
@end
@implementation ThreeDTransViewController
- (void)viewDidLoad {
[super viewDidLoad];
//初始化CATransform3D
CATransform3D transForm = CATransform3DIdentity;
//m34決定遠近縮放
transForm.m34 = - 1.0 / 500.0;
//旋轉M_PI_4
transForm = CATransform3DRotate(transForm, M_PI_4, 0, 1, 0);
//應用帶Layer
_imgView.layer.transform= transForm;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
立體模型
我們知道3D變換,那固體模型也可以通過3D變換做出來了。具體看程式碼備註//
// StereomodelViewController.m
// LayerStudyDemo
//
// Created by apple on 2017/10/10.
// Copyright © 2017年 ZY. All rights reserved.
//
#import "StereomodelViewController.h"
#import <GLKit/GLKit.h>
#define LIGHT_DIRECTION 0, 1, -0.5
#define AMBIENT_LIGHT 0.5
@interface StereomodelViewController ()
@property (strong, nonatomic) IBOutletCollection(UIView) NSArray *faceViews;
@end
@implementation StereomodelViewController
- (void)viewDidLoad {
[super viewDidLoad];
//建立CATransform3D
CATransform3D perspective = CATransform3DIdentity;
//滅點 物體遠近縮放比例
perspective.m34 = -1.0 / 500.0;
//X軸旋轉M_PI_4
perspective = CATransform3DRotate(perspective, -M_PI_4, 1, 0, 0);
//Y軸旋轉M_PI_4
perspective = CATransform3DRotate(perspective, -M_PI_4, 0, 1, 0);
//子Layer整體應用此CATransform3D
self.view.layer.sublayerTransform = perspective;
[self setRectModel];
}
//新增正方形View到介面,然後組裝
-(void)addFaceViewInContainViewWithTransform:(CATransform3D)transform andIndex:(NSUInteger)index{
UIView * faceView = _faceViews[index];
faceView.layer.borderWidth = 1;
faceView.layer.borderColor = [UIColor blackColor].CGColor;
[self.view addSubview:faceView];
faceView.center = self.view.center;
faceView.layer.transform = transform;
[self applyLightingToFace:faceView.layer];
}
//沒有實現光線陰影效果,回來找BUG
- (void)applyLightingToFace:(CALayer *)face
{
//add lighting layer
CALayer *layer = [CALayer layer];
layer.frame = face.bounds;
[face addSublayer:layer];
//convert the face transform to matrix
//(GLKMatrix4 has the same structure as CATransform3D)
//譯者注:GLKMatrix4和CATransform3D記憶體結構一致,但座標型別有長度區別,所以理論上應該做一次float到CGFloat的轉換,感謝[@zihuyishi](https://github.com/zihuyishi)同學~
CATransform3D transform = face.transform;
GLKMatrix4 matrix4 = *(GLKMatrix4 *)&transform;
GLKMatrix3 matrix3 = GLKMatrix4GetMatrix3(matrix4);
//get face normal
GLKVector3 normal = GLKVector3Make(0, 0, 1);
normal = GLKMatrix3MultiplyVector3(matrix3, normal);
normal = GLKVector3Normalize(normal);
//get dot product with light direction
GLKVector3 light = GLKVector3Normalize(GLKVector3Make(LIGHT_DIRECTION));
float dotProduct = GLKVector3DotProduct(light, normal);
//set lighting layer opacity
CGFloat shadow = 1 + dotProduct - AMBIENT_LIGHT;
UIColor *color = [UIColor colorWithWhite:0 alpha:shadow];
layer.backgroundColor = color.CGColor;
}
-(void)setRectModel{
// CATransform3D transform = CATransform3DIdentity;
// transform = CATransform3DTranslate(transform, 0,0, 100);
// [self addFaceViewInContainViewWithTransform:transform andIndex:0];
// CATransform3D transform1 = CATransform3DIdentity;
// transform1 = CATransform3DTranslate(transform1, 100,0, 0);
// transform1 = CATransform3DRotate(transform1, M_PI_2, 0, 1, 0);
// [self addFaceViewInContainViewWithTransform:transform1 andIndex:1];
// CATransform3D transform2 = CATransform3DIdentity;
// transform2 = CATransform3DTranslate(transform2, 0,100, 0);
// transform2 = CATransform3DRotate(transform2, M_PI_2, 0, 1, 0);
// [self addFaceViewInContainViewWithTransform:transform2 andIndex:2];
// [self addFaceViewInContainViewWithTransform:CATransform3DIdentity andIndex:3];
// [self addFaceViewInContainViewWithTransform:CATransform3DIdentity andIndex:4];
// [self addFaceViewInContainViewWithTransform:CATransform3DIdentity andIndex:5];
//add cube face 1
CATransform3D transform = CATransform3DMakeTranslation(0, 0, 50);
[self addFaceViewInContainViewWithTransform:transform andIndex:0];
//add cube face 2
transform = CATransform3DMakeTranslation(50, 0, 0);
transform = CATransform3DRotate(transform, M_PI_2, 0, 1, 0);
[self addFaceViewInContainViewWithTransform:transform andIndex:1];
//add cube face 3
transform = CATransform3DMakeTranslation(0, -50, 0);
transform = CATransform3DRotate(transform, M_PI_2, 1, 0, 0);
[self addFaceViewInContainViewWithTransform:transform andIndex:2];
//add cube face 4
transform = CATransform3DMakeTranslation(0, 50, 0);
transform = CATransform3DRotate(transform, -M_PI_2, 1, 0, 0);
[self addFaceViewInContainViewWithTransform:transform andIndex:3];
//add cube face 5
transform = CATransform3DMakeTranslation(-50, 0, 0);
transform = CATransform3DRotate(transform, -M_PI_2, 0, 1, 0);
[self addFaceViewInContainViewWithTransform:transform andIndex:4];
//add cube face 6
transform = CATransform3DMakeTranslation(0, 0, -50);
transform = CATransform3DRotate(transform, M_PI, 0, 1, 0);
[self addFaceViewInContainViewWithTransform:transform andIndex:5];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
這裡注意的是各個面的點選事件,其實每個面的響應事件是我們二維放置順序排列的,也就是說6壓著5,5壓著4這種順序,那麼你想響應2的點選事件應該怎麼辦呢,一種方法就是2以上的userInteractionEnabled 屬性設定為NO,這樣上面的層就不會阻斷響應了。具體怎麼做,實際應該在具體操作。
相關文章
- Core Animation總結
- Core Animation 之 ViewView
- 核心動畫(Core Animation Programming)動畫
- Core Animation Programming Guide Mind MappingGUIIDEAPP
- Flowable實戰(五)表單和流程變數變數
- 視覺效果 -- iOS Core Animation 系列三視覺iOS
- Flutter開發實戰分析-animation_demo解析導讀Flutter
- java core dump分析實戰Java
- 玩轉iOS開發:7.《Core Animation》Implicit AnimationsiOS
- iOS開發UI篇--iOS動畫(Core Animation)總結iOSUI動畫
- 基於 abp vNext 和 .NET Core 開發部落格專案 - Blazor 實戰系列(五)Blazor
- javascript動態改變css3的animationJavaScriptCSSS3
- Dapr + .NET Core實戰(六)繫結
- 玩轉iOS開發:6.《Core Animation》CALayer的Specialized LayersiOSZed
- 基於 abp vNext 和 .NET Core 開發部落格專案 - 部落格介面實戰篇(五)
- spring4.1.8擴充套件實戰之五:改變bean的定義(BeanFactoryPostProcessor介面)Spring套件Bean
- Elasticsearch搜尋功能的實現(五)-- 實戰Elasticsearch
- OpenFaaS實戰之五:大話watchdog
- client-go實戰之五:DiscoveryClientclientGo
- kubebuilder實戰之五:operator編碼UI
- Spring框架(五)實戰Spring整合MybatisSpring框架MyBatis
- Python 實現影像快速傅立葉變換和離散餘弦變換Python
- 【asp.net core 系列】10 實戰之ActionFilterASP.NETFilter
- .NET Core+MongoDB叢集搭建與實戰MongoDB
- Dapr + .NET Core實戰(八)服務監測
- .NET Core3.1 Dotnetty實戰系列視訊Netty
- Spiral animation
- 快速傅立葉變換及其實現
- Kotlin實戰【五】Kotlin中的異常Kotlin
- 【asp.net core 系列】8 實戰之 利用 EF Core 完成資料操作層的實現ASP.NET
- ASP.NET Core 專案實戰(持續更新~~~)ASP.NET
- csredis-in-asp.net core理論實戰-使用示例RedisASP.NET
- Dapr + .NET Core實戰(十三)跨語言開發
- Dapr + .NET Core實戰(十二)服務呼叫之GRPCRPC
- z 變換
- Hough變換
- Excel 多個變數替換 實際值Excel變數
- Docker最全教程——從理論到實戰(五)Docker
- Spring Cloud Gateway實戰之五:內建filterSpringCloudGatewayFilter