IOS Core Animation Advanced Techniques Study Notes (4)

Source: Internet
Author: User

Chapter 5: Transforms


Affine Transforms

CGAffineTransform is two-dimensional




Creating a CGAffineTransform

There are three main ways to rotate: CGAffineTransformMakeRotation (CGFloat angle)



Scaling: CGAffineTransformMakeScale (CGFloat sx, CGFloat sy)


Mobile: CGAffineTransfZ messages? Http://www.bkjia.com/kf/ware/vc/ "target =" _ blank "class =" keylink "> accuracy + Cgo8aW1nIHNyYz0 =" http://www.2cto.com/uploadfile/Collfiles/20140517/2014051709101437.png "alt =" \ ">



Case 5.1 CGAffineTransformMakeRotation

Source code download here: http://www.informit.com/title/9780133440751

@interface ViewController ()@property (nonatomic, weak) IBOutlet UIView *layerView;@end@implementation ViewController- (void)viewDidLoad{    [super viewDidLoad];    //rotate the layer 45 degrees    CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI_4);    self.layerView.layer.affineTransform = transform;}@end


Modify CGAffineTransformMakeScale
- (void)viewDidLoad{    [super viewDidLoad];    //rotate the layer 45 degrees    CGAffineTransform transform = CGAffineTransformMakeScale(0.5, 0.5);    self.layerView.layer.affineTransform = transform;}


Modify CGAffineTransformMakeTranslation
- (void)viewDidLoad{    [super viewDidLoad];    //rotate the layer 45 degrees    CGAffineTransform transform = CGAffineTransformMakeTranslation(-50.0, 30.0);    self.layerView.layer.affineTransform = transform;}




Combining Transforms

Method 1: Use CGAffineTransformConcat
Continue to modify Example 5.1
- (void)viewDidLoad{    [super viewDidLoad];    //rotate the layer 45 degrees    CGAffineTransform transform1 = CGAffineTransformMakeRotation(M_PI_4);    CGAffineTransform transform2 = CGAffineTransformMakeScale(0.5, 0.5);    CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);    self.layerView.layer.affineTransform = transform;}


Method 2: CGAffineTransformRotate (CGAffineTransform t, CGFloat angle)
CGAffineTransformScale (CGAffineTransform t, CGFloat sx, CGFloat sy)
CGAffineTransformTranslate (CGAffineTransform t, CGFloat tx, CGFloat ty) is the same as the previous CGAffineTransformMakeRotation function. You can also use the combine function to initialize CGAffineTransform t

Example 5.2
@interface ViewController ()@property (nonatomic, weak) IBOutlet UIView *layerView;@end@implementation ViewController- (void)viewDidLoad{    [super viewDidLoad];    //create a new transform    CGAffineTransform transform = CGAffineTransformIdentity;        //scale by 50%    transform = CGAffineTransformScale(transform, 0.5, 0.5);        //rotate by 30 degrees    transform = CGAffineTransformRotate(transform, M_PI / 180.0 * 30.0);        //translate by 200 points    transform = CGAffineTransformTranslate(transform, 200, 0);        //apply transform to layer    self.layerView.layer.affineTransform = transform;}@end



The following are some special values: 1. First, you must know the initialization result of the function CGAffineTransformIdentity.

2. flip around CGAffineTransformMake );

3. Flip CGAffineTransformMake (-, self. layerView. frame. size. width, 0) to the right of the axis );

4. Flip up and down

CGAffineTransformMake (, 0,-, 0 );



5. Flip CGAffineTransformMake (, 0,-, self. layerView. frame. size. height) along the bottom side in an axial manner );

6. Convert to 180 ° CGAffineTransformMake (-, 0,-, 0 );

7. In the example 5.3, the CGAffineTransformMake (,-,) is hashed to the right. Code:
@interface ViewController ()@property (nonatomic, weak) IBOutlet UIView *layerView;@end@implementation ViewControllerCGAffineTransform CGAffineTransformMakeShear(CGFloat x, CGFloat y){    CGAffineTransform transform = CGAffineTransformIdentity;    transform.c = -x;    transform.b = y;    return transform;}- (void)viewDidLoad{    [super viewDidLoad];    //shear the layer at a 45-degree angle    self.layerView.layer.affineTransform = CGAffineTransformMakeShear(1, 0);}@end


8. In example 5.3, the CGAffineTransformMake (1, 1, 0, 0) is dropped to the left );



3D Transforms

Similar to CGAffineTransform, CATransform3D is 3D.

CATransform3D is a structure. He has his own formula that can be applied.

Struct CATransform3D

{

CGFloat m11 (x scaling), m12 (y shear), m13 (rotation), m14 ();

CGFloat m21 (x shear), m22 (y scaling), m23 (), m24 ();

CGFloat m31 (rotation), m32 (), m33 (), m34 (perspective effect, the object to be operated must have a rotation angle, otherwise there is no effect. Integrity/Negative values make sense );

CGFloat m41 (x translation), m42 (y translation), m43 (z translation), m44 ();

};



There are also three transformation methods
Rotation: CATransform3DMakeRotation (CGFloat angle, CGFloat x, CGFloat y, CGFloat z) first, you must know what x, y, and z are.
A vector composed of {x, y, z} is the axis used for rotation, and angle is the rotation angle.

Example: source Image

Rotate 45 degrees toward the X axis. Rotate 45 degrees to the Y axis. Rotate 45 degrees to the Z axis.


To the X axis, the Y axis is rotated 45 degrees, that is, along the diagonal line.




Scaling: CATransform3DMakeScale (CGFloat sx, CGFloat sy, CGFloat sz)

Sx: X-axis scaling, which represents a scaling ratio. Generally, it is a number between 0 and 1.

Sy: Y-axis scaling.

Sz: when the overall scale is changed, that is, when m11 (sx) = m22 (sy), if m33 (sz)> 1, the overall scale is reduced,

If 0 <m33 (sz) <1, the overall image is enlarged,

If m33 (sz) is <0, symmetric proportional transformation is performed on the origin.


When sx = 1, sy = 1.


When sx = 0.5, sy = 0.5.




Transform: CATransform3DMakeTranslation (Gloat tx, CGFloat ty, CGFloat tz)

T' = [1 0 0 0; 0 1 0 0; 0 0 1 0; tx ty tz 1]

1 0 0 0

0 1 0 0

0 0 1 0

Tx ty tz 1

It is obvious to look at the data structure above.


Tx: The X-axis offset, which is a positive number down.

Ty: Y-axis offset, positive to the right.

Tz: The Z axis offset position, which is a positive number.



You can directly modify the data structure to set the transformation effect.

Struct CATransform3D

{

CGFloat m11, m12, m13, m14;

CGFloat m21, m22, m23, m24;

CGFloat m31, m32, m33, m34;

CGFloat m41, m42, m43, m44;

}

    CATransform3D transform = CATransform3DMakeRotation(M_PI_4, 0, 1, 0);    transform.m11 = 2;

Or modify the key value.

    [myLayer setValue:[NSNumber numberWithInt:0] forKeyPath:@"transform.rotation.x"];




Example 5.4
@interface ViewController ()@property (nonatomic, weak) IBOutlet UIView *layerView;@end@implementation ViewController- (void)viewDidLoad{    [super viewDidLoad];    //rotate the layer 45 degrees along the Y axis    CATransform3D transform = CATransform3DMakeRotation(M_PI_4, 0, 1, 0);    self.layerView.layer.transform = transform;}@end


Modify example 5.4, modify from http://lepetit-prince.net/ios? P = 451
#import "ViewController.h"#import 
 
  @interface ViewController (){    BOOL front;}@property (nonatomic, weak) IBOutlet UIView *layerView;@end@implementation ViewController- (void)viewDidLoad{    [super viewDidLoad];    front = YES;    self.layerView.layer.contents = (__bridge id)([UIImage imageNamed:@"front.png"].CGImage);}- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{    [UIView animateWithDuration:0.5 animations:^{        self.layerView.layer.transform = CATransform3DMakeRotation(M_PI * 0.5, 0.0f, 1.0f, 0.0f);    } completion:^(BOOL finished) {        self.layerView.layer.transform = CATransform3DMakeRotation(M_PI * 1.5, 0.0f, 1.0f, 0.0f);        self.layerView.layer.contents = front ? (__bridge id)([UIImage imageNamed:@"back.png"].CGImage) : (__bridge id)([UIImage imageNamed:@"front.png"].CGImage);        [UIView animateWithDuration:0.5 animations:^{            self.layerView.layer.transform = CATransform3DMakeRotation(M_PI * 2, 0.0f, 1.0f, 0.0f);        } completion:^(BOOL finished) {            front = !front;        }];    }];}@end
 
Resource file front.png back.png


Perspective Projection

Previously mentioned m34 (perspective effect, the object to be operated must have a rotation angle, otherwise there is no effect. Integrity/Negative values make sense)
Example 5.5
@interface ViewController ()@property (nonatomic, weak) IBOutlet UIView *layerView;@end@implementation ViewController- (void)viewDidLoad{    [super viewDidLoad];        //create a new transform    CATransform3D transform = CATransform3DIdentity;        //apply perspective    transform.m34 = - 1.0 / 500.0;    //rotate by 45 degrees along the Y axis    transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0);        //apply to layer    self.layerView.layer.transform = transform;}@end


If you comment out the rotation, see what the result will be.
    //rotate by 45 degrees along the Y axis    //transform = CATransform3DRotate(transform, M_PI_4, 0, 1, 0);

In this example, the perspective scenario is ± 1. 0/d. The distance from the d lens to the scene is 500 ~ 1000 the best effect, + representing the direction

The Vanishing Point

When the scene is slowly away from the camera, the Vanishing Point will eventually converge as it gets smaller and smaller)
In general, the point is in the center of the view, or in the center that contains all the scenes.

Core Animation defines the destroy point in anchorPoint. Therefore, before the transformation, determine anchorPoint,
In particular, it is best to ensure that all layeys in the same view have the same extinction point during 3D transformation.

The sublayerTransform Property

If you have multiple views or layers with the same 3D transformations, you can use sublayerTransform,

SublayerTransform is also CATransform3D, and only sublayers can respond.

The default value is Identity Transform (CATransform3DIdentity)


Example 5.6
@interface ViewController ()@property (nonatomic, weak) IBOutlet UIView *containerView;@property (nonatomic, weak) IBOutlet UIView *layerView1;@property (nonatomic, weak) IBOutlet UIView *layerView2;@end@implementation ViewController- (void)viewDidLoad{    [super viewDidLoad];        //apply perspective transform to container    CATransform3D perspective = CATransform3DIdentity;    perspective.m34 = - 1.0 / 500.0;    self.containerView.layer.sublayerTransform = perspective;    //rotate layerView1 by 45 degrees along the Y axis    CATransform3D transform1 = CATransform3DMakeRotation(M_PI_4, 0, 1, 0);    self.layerView1.layer.transform = transform1;        //rotate layerView2 by 45 degrees along the Y axis    CATransform3D transform2 = CATransform3DMakeRotation(-M_PI_4, 0, 1, 0);    self.layerView2.layer.transform = transform2;}@end


Let's move the Image Location in xib:
Check the result again.

Restore the xib file and modify the code.
- (void)viewDidLoad{    [super viewDidLoad];        //apply perspective transform to container//    CATransform3D perspective = CATransform3DIdentity;//    perspective.m34 = - 1.0 / 500.0;//    self.containerView.layer.sublayerTransform = perspective;    //apply perspective    CATransform3D transform1 = CATransform3DIdentity;    transform1.m34 = - 1.0 / 500.0;    transform1 = CATransform3DRotate(transform1, M_PI_4, 0, 1, 0);    self.layerView1.layer.transform = transform1;        //rotate layerView2 by 45 degrees along the Y axis    CATransform3D transform2 = CATransform3DIdentity;    transform2.m34 = - 1.0 / 500.0;    transform2 = CATransform3DRotate(transform2, -M_PI_4, 0, 1, 0);    self.layerView2.layer.transform = transform2;}


The result is the same as the original one, but the xib file is modified again, and the image is moved to view the result, which compares the effect when the code is not modified.

Are you aware of the benefits of setting sublayerTransform?
1. you can set the effect of all sublayers at a time. the Vanishing Point is set in the center of the container layer, that is, the parent layer. This means that no matter how you modify the position or frame of the subLayer, they will maintain the same extinction Point.

Backfaces

In Example 5.4, we set the rotation M_PI_4 (45 °) to M_PI (180 °)
- (void)viewDidLoad{    [super viewDidLoad];    //rotate the layer 45 degrees along the Y axis    CATransform3D transform = CATransform3DMakeRotation(M_PI, 0, 1, 0);    self.layerView.layer.transform = transform;}


After turning to the back of the layer, the original image is displayed. It can be seen that the layer is double-sided, and both sides are depicted. Therefore, we will think about why we need to waste GPU to depict what we don't see. Another attribute of CALayer doubleSided can solve this problem.
Add doubleSided settings to the Code in example 5.4 that has just been modified.
- (void)viewDidLoad{    [super viewDidLoad];    //rotate the layer 45 degrees along the Y axis    CATransform3D transform = CATransform3DMakeRotation(M_PI, 0, 1, 0);    self.layerView.layer.transform = transform;    self.layerView.layer.doubleSided = NO;}

Image gone


Layer Flattening
Let's take a look at the example. Example 5.7 and 5.8

Solid Objects
Let's take a look at the example. Example 5.9 and 5.10





Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.