< Previous PageNext Page > Hide TOC

Layer Geometry and Transforms

This chapter describes the components of a layer’s geometry, how they interrelate, and how transform matrices can produce complex visual effects.

Contents:

Layer Coordinate System
Specifying a Layer’s Geometry
Transforming a Layer’s Geometry


Layer Coordinate System

The layer's location and size are expressed using the same coordinate system that the Quartz graphics environment uses. By default, the graphics environment origin (0.0,0.0) is located in the lower left, and values are specified as floating-point numbers that increase up and to the right in coordinate system units. The coordinate system units, the unit square, is the size of a 1.0 by 1.0 rectangle.

Every layer instance defines and maintains its own coordinate system, and all sublayers are positioned, and drawing is done, relative to this coordinate system. Methods are provided to convert points, rectangles and sizes from one layer coordinate system to another. A layer's coordinate system should be considered the base coordinate system for all the content of the layer, including its sublayers.

iPhone OS Note: The default root layer of a UIView instance uses a flipped coordinate system that matches the default coordinate system of a UIView instance–the origin is in the top-left and values increase down and to the right. Layers created by instantiating CALayer directly use the standard Core Animation coordinate system.

Specifying a Layer’s Geometry

While layers and the layer-tree are analogous to Cocoa views and the view hierarchy in many ways, how a layer's geometry is specified is different, and often simpler, manner. All of a layer’s geometric properties, including the layer’s transform matrices, can be implicitly and explicitly animated.

Figure 1 shows the properties used to specify a layer's geometry in context.


Figure 1  CALayer geometry properties

CALayer geometry properties

The position property is a CGPoint that specifies the position of the layer relative to its superlayer, and is expressed in the superlayer's coordinate system.

The bounds property is a CGRect that provides the size of the layer (bounds.size) and the origin (bounds.origin). The bounds origin is used as the origin of the graphics context when you override a layer's drawing methods.

Layers have an implicit frame that is a function of the position, bounds, anchorPoint, and transform properties. Setting a new frame rectangle changes the layer's position and bounds properties appropriately, but the frame itself is not stored. When a new frame rectangle is specified the bounds origin is undisturbed, while the bounds size is set to the size of the frame. The layer's position is set to the proper location relative to the anchor point. When you get the frame property value, it is calculated relative to the position, bounds, and anchorPoint properties.

The anchorPoint property is a CGPoint that specifies a location within the bounds of a layer that corresponds with the position coordinate. The anchor point specifies how the bounds are positioned relative to the position property, as well as serving as the point that transforms are applied around. It is expressed in the unit coordinate system-the lower left of the layer bounds is 0.0,0.0, and the upper right is 1.0,1.0.

When you specify the frame of a layer, position is set relative to the anchor point. When you specify the position of the layer, bounds is set relative to the anchor point.

Figure 2 shows three example values for an anchor point.


Figure 2  Three anchorPoint values

Three anchorPoint values

The default value for anchorPoint is (0.5,0.5) which corresponds to the center of the layer's bounds (shown as point A in Figure 2.) Point B shows the position of an anchor point set to (0.0,0.5). Finally, point C (1.0,0.0) causes specifies that the layer’s position is set to the bottom right corner of the frame.

The relationship of the frame, bounds, position, and anchorPoint properties is shown in Figure 3.


Figure 3  Layer Origin of (0.5,0.5)

Layer Origin of (0.5,0.5)

In this example the anchorPoint is set to the default value of (0.5,0.5), which corresponds to the center of the layer. The position of the layer is set to (100.0,100.0), and the bounds is set to the rectangle (0.0, 0.0, 120.0, 80.0). This causes the frame property to be calculated as (40.0, 60.0, 120.0, 80.0).

If you created a new layer, and set only the layer’s frame property to (40.0, 60.0, 120.0, 80.0), the position property would be automatically set to (100.0,100.0), and the bounds property to (0.0, 0.0, 120.0, 80.0).

Figure 4 shows a layer with the same frame rectangle as the layer in Figure 3. However, in this case the anchorPoint of the layer is set to (0.0,0.0), which corresponds with the bottom left corner of the layer.


Figure 4  Layer Origin of (0.0,0.0)

Layer Origin of (0.0,0.0)

With the frame set to (40.0, 60.0, 120.0, 80.0), the value of the bounds property is the same, but the value of the position property has changed.

Another aspect of layer geometry that differs from Cocoa views is that you can specify a radius that is used to round the corners of the layer. The cornerRadius property specifies a radius the layer uses when drawing content, clipping sublayers, and drawing the border and shadow.

The zPosition property specifies the z-axis component of the layer's position. The zPosition is intended to be used to set the visual position of the layer relative to its sibling layers. It should not be used to specify the order of layer siblings, instead reorder the layer in the sublayer array.

Transforming a Layer’s Geometry

Once established, you can transform a layer's geometry using matrix transformations. The Transform data structure defines a homogenous three-dimensional transform (a 4 by 4 matrix of CGFloat values) that is used to rotate, scale, offset, skew, and apply perspective transformations to a layer.

Two layer properties specify transform matrices: transform and sublayerTransform. The matrix specified by the transform property is applied to the layer and its sublayers relative to the layer's anchorPoint. Figure 3 shows how rotation and scaling transforms affect a layer when using an anchorPoint of (0.5,0.5), the default value. Figure 4 shows how the same transform matrices affect a layer when an anchorPoint of (0.0,0.0). The matrix specified by the sublayerTransform property is applied only to the layer’s sublayers, rather than to the layer itself.

You create and modify CATransform3D data structures in one of the following ways:

The constant CATransform3DIdentity is the identity matrix, a matrix that has no scale, rotation, skewing, or perspective applied. Applying the identity matrix to a layer causes it to be displayed with its default geometry.

Transform Functions

The transform functions available in Core Animation operate on matrices. You can use these functions (shown in Table 1) to construct a matrix that you later apply to a layer or its sublayers by modifying the transform or sublayerTransform properties respectively. The transform functions either operate on, or return, a CATransform3D data structure. This enables you to construct simple or complex transforms that you can readily reuse.

Table 1  CATransform3D transform functions for translation, rotation, and scaling

Function

Use

CATransform3DMakeTranslation

Returns a transform that translates by '(tx, ty, tz)'. t' = [1 0 0 0; 0 1 0 0; 0 0 1 0; tx ty tz 1].

CATransform3DTranslate

Translate 't' by '(tx, ty, tz)' and return the result: * t' = translate(tx, ty, tz) * t.

CATransform3DMakeScale

Returns a transform that scales by `(sx, sy, sz)': * t' = [sx 0 0 0; 0 sy 0 0; 0 0 sz 0; 0 0 0 1].

CATransform3DScale

Scale 't' by '(sx, sy, sz)' and return the result: * t' = scale(sx, sy, sz) * t.

CATransform3DMakeRotation

Returns a transform that rotates by 'angle' radians about the vector '(x, y, z)'. If the vector has length zero the identity transform is returned.

CATransform3DRotate

Rotate 't' by 'angle' radians about the vector '(x, y, z)' and return the result. t' = rotation(angle, x, y, z) * t.

The angles of rotation is specified in radians rather than degrees. The following functions allow you to convert between radians and degrees.

CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;};
CGFloat RadiansToDegrees(CGFloat radians) {return radians * 180 / M_PI;};

Core Animation provides a transform function that inverts a matrix, CATransform3DInvert. Inversion is generally used to provide reverse transformation of points within transformed objects. Inversion can be useful when you need to recover a value that has been transformed by a matrix: invert the matrix, and multiply the value by the inverted matrix, and the result is the original value.

Functions are also provided that allow you to convert a CATransform3D matrix to a CGAffineTransform matrix, if the CATransform3D matrix can be expressed as such.

Table 2  CATransform3D transform functions for CGAffineTransform conversion

Function

Use

CATransform3DMakeAffineTransform

Returns a CATransform3D with the same effect as the passed affine transform.

CATransform3DIsAffine

Returns YES if the passed CATransform3D can be exactly represented an affine transform.

CATransform3DGetAffineTransform

Returns the affine transform represented by the passed CATransform3D.

Functions are provided for comparing transform matrices for equality with the identity matrix, or another transform matrix.

Table 3  CATransform3D transform functions for testing equality

Function

Use

CATransform3DIsIdentity

Returns YES if the transform is the identity transform.

CATransform3DEqualToTransform

Returns YES if the two transforms are exactly equal..

Modifying the Transform Data Structure

You can modify the value of any of the CATransform3D data structure members as you would any other data structure. Listing 1 contains the definition of the CATransform3D data structure, the structure members are shown in their corresponding matrix positions.

Listing 1  CATransform3D structure

 
struct CATransform3D
{
  CGFloat m11, m12, m13, m14;
  CGFloat m21, m22, m23, m24;
  CGFloat m31, m32, m33, m34;
  CGFloat m41, m42, m43, m44;
};
 
typedef struct CATransform3D CATransform3D;

The example in Listing 2 illustrates how to configure a CATransform3D as a perspective transform.

Listing 2  Modifying the CATransform3D data structure directly

 CATransform3D aTransform = CATransform3DIdentity;
// the value of zDistance affects the sharpness of the transform.
zDistance = 850;
aTransform.m34 = 1.0 / -zDistance;

Modifying a Transform Using Key Paths

Core Animation extends the key-value coding protocol to allow getting and setting of the commonly values of a layer's CATransform3D matrix through key paths. Table 4 describes the key paths for which a layer’s transform and sublayerTransform properties are key-value coding and observing compliant.

Table 4  CATransform3D key paths

Field Key Path

Description

rotation.x

The rotation, in radians, in the x axis.

rotation.y

The rotation, in radians, in the y axis.

rotation.z

The rotation, in radians, in the z axis.

rotation

The rotation, in radians, in the z axis. This is identical to setting the rotation.z field.

scale.x

Scale factor for the x axis.

scale.y

Scale factor for the y axis.

scale.z

Scale factor for the z axis.

scale

Average of all three scale factors.

translation.x

Translate in the x axis.

translation.y

Translate in the y axis.

translation.z

Translate in the z axis.

translation

Translate in the x and y axis. Value is an NSSize or CGSize.

You can not specify a structure field key path using Objective-C 2.0 properties. This will not work:

myLayer.transform.rotation.x=0;

Instead you must use setValue:forKeyPath: or valueForKeyPath: as shown below:

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


< Previous PageNext Page > Hide TOC


© 2008 Apple Inc. All Rights Reserved. (Last updated: 2008-11-13)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.