Core Animation实战五(变换)

来源:互联网 发布:安卓组态软件 编辑:程序博客网 时间:2024/05/18 01:51

变化效果:


    仿射变换

仿射变化自己简单的理解就是利用线性代数矩阵的变换得到一个新的点的变化。

iOS API主要有这三个方法,大小缩放,旋转角度变化和位置变化

/* 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轴变化。


Demo:

////  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变换做出来了。具体看代码备注

Demo:

////  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,这样上面的层就不会阻断响应了。具体怎么做,实际应该在具体操作。

DEMO地址

原创粉丝点击