前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Core Animation实战五(变换)

Core Animation实战五(变换)

作者头像
星宇大前端
发布2019-01-15 15:12:21
4200
发布2019-01-15 15:12:21
举报
文章被收录于专栏:大宇笔记

变化效果:

仿射变换

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

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:

代码语言:javascript
复制
//
//  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:

代码语言:javascript
复制
//
//  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:

代码语言:javascript
复制
//
//  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地址

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017年11月01日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 仿射变换
  • 3D仿射变换
  • 立体模型
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档