Quartz provides two opaque data types for creating gradients—CGShadingRef
and CGGradientRef
.
An axial gradient (also called a linear gradient) varies along an axis between two defined end points. All points that lie on a line perpendicular to the axis have the same color value.
A radial gradient is a fill that varies radially along an axis between two defined ends, which typically are both circles. Points share the same color value if they lie on the circumference of a circle whose center point falls on the axis.
A Comparison of CGShading and CGGradient Objects
TheCGShadingRef
opaque data type gives you control over how the color at each point in the gradient is computed. Before you can create a CGShading object, you must create a CGFunction object (
CGFunctionRef
) that defines a function for computing colors in the gradient.
A CGGradient object is a subset of a CGShading object that’s designed with ease-of-use in mind. The CGGradientRef
opaque data type is straightforward to use because Quartz calculates the color at each point in the gradient for you—you don’t supply a gradient calculation function.
CGGradient | CGShading |
---|---|
Can use the same object to draw axial and radial gradients. | Need to create separate objects for axial and radial gradients. |
Set the geometry of the gradient at drawing time. | Set the geometry of the gradient at object creation time. |
Quartz calculates the colors for each point in the gradient. | You must supply a callback function that calculates the colors for each point in the gradient. |
Easy to define more than two locations and colors. | Need to design your callback to use more than two locations and colors, so it takes a bit more work on your part. |
Extending Color Beyond the End of a Gradient
When you create a gradient, you have the option of filling the space beyond the ends of the gradient with a solid color. Quartz uses the color defined at the boundary of the gradient as the fill color.
Using a CGGradient Object
The CGGradient object is an abstract definition of a gradient—it simply specifies colors and locations, but not the geometry. You can use this same object for both axial and radial geometries.
Using a CGGradient object to create and draw a gradient is fairly straightforward, requiring these steps:
-
Create a CGGradient object, supplying a color space, an array of two or more color components, an array of two or more locations, and the number of items in each of the two arrays.
-
Paint the gradient by calling either
CGContextDrawLinearGradient
orCGContextDrawRadialGradient
and supplying a context, a CGGradient object, drawing options, and the stating and ending geometry (points for axial gradients or circle centers and radii for radial gradients). -
Release the CGGradient object when you no longer need it.
CGFloat
value in the range of 0.0 to 1.0, inclusive, that specifies the normalized distance along the axis of the gradient. A value of 0.0 specifies the starting point of the axis, while 1.0 specifies the ending point of the axis. If you pass NULL
for the locations array, Quartz uses 0 for the first location and 1 for the second.
The number of color components per color depends on the color space. For onscreen drawing, you’ll use an RGB color space. Because Quartz draws with alpha, each onscreen color has four components—red, green, blue, and alpha. So, for onscreen drawing, the number of elements in the color component array that you provide must contain four times the number of locations.
Creating a CGGradient object
CGGradientRef myGradient; |
CGColorSpaceRef myColorspace; |
size_t num_locations = 2; |
CGFloat locations[2] = { 0.0, 1.0 }; |
CGFloat components[8] = { 1.0, 0.5, 0.4, 1.0, // Start color |
0.8, 0.8, 0.3, 1.0 }; // End color |
|
myColorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); |
myGradient = CGGradientCreateWithColorComponents (myColorspace, components, |
locations, num_locations); |
Painting an axial gradient using a CGGradient object
CGPoint myStartPoint, myEndPoint; |
myStartPoint.x = 0.0; |
myStartPoint.y = 0.0; |
myEndPoint.x = 1.0; |
myEndPoint.y = 1.0; |
CGContextDrawLinearGradient (myContext, myGradient, myStartPoint, myEndPoint, 0); |
Listing 8-3 is a code fragment that uses the CGGradient object created in Listing 8-1 to paint the radial gradient shown in Figure 8-9. This example illustrates the result of extending the area of the gradient by filling it with a solid color.
Painting a radial gradient using a CGGradient object
CGPoint myStartPoint, myEndPoint; |
CGFloat myStartRadius, myEndRadius; |
myStartPoint.x = 0.15; |
myStartPoint.y = 0.15; |
myEndPoint.x = 0.5; |
myEndPoint.y = 0.5; |
myStartRadius = 0.1; |
myEndRadius = 0.25; |
CGContextDrawRadialGradient (myContext, myGradient, myStartPoint, |
myStartRadius, myEndPoint, myEndRadius, |
kCGGradientDrawsAfterEndLocation) |
The radial gradient shown in Figure 8-4 was created using the variables shown in Listing 8-4.
The variables used to create a radial gradient by varying alpha
CGPoint myStartPoint, myEndPoint; |
CGFloat myStartRadius, myEndRadius; |
myStartPoint.x = 0.2; |
myStartPoint.y = 0.5; |
myEndPoint.x = 0.65; |
myEndPoint.y = 0.5; |
myStartRadius = 0.1; |
myEndRadius = 0.25; |
size_t num_locations = 2; |
CGFloat locations[2] = { 0, 1.0 }; |
CGFloat components[8] = { 0.95, 0.3, 0.4, 1.0, |
0.95, 0.3, 0.4, 0.1 }; |
Listing 8-5 shows the variables used to create the gray gradient shown in Figure 8-10, which has three locations.
The variables used to create a gray gradient
size_t num_locations = 3; |
CGFloat locations[3] = { 0.0, 0.5, 1.0}; |
CGFloat components[12] = { 1.0, 1.0, 1.0, 1.0, |
0.5, 0.5, 0.5, 1.0, |
1.0, 1.0, 1.0, 1.0 } |