2008 05 14Projected coordinates of a 3D CALayer
CALayer, but you can use convertRect:fromLayer to almost get them. Thanks to Simon Fraser on the Quartz ML for that.
Suppose you have layers setup like that :
rootLayer
layerHavingA3DTransform
layer1
layer2
layer3
layer1, layer2, layer3 will be transformed by layerHavingA3DTransform and will appear 3D. To get their projected coordinates, use
CGRect projectedRect = [layer1 convertRect:localRect toLayer:[self layer]];
This will transform localRect, a rect in layer1 coordinates to root layer coordinates. If you want the layer extent, that's -bounds.width/2, -bounds.height/2, bounds.width, bounds.height for the default anchorPoint of (0.5, 0.5). Note that projectedRect is in layer coordinates, not in NSView coordinates. For this case I had manually centered layerHavingA3DTransform in the view and got coordinates reflecting that, going from -size to +size.
convertPoint:fromLayer to convert each layer point. 2008 05 10Oval radial gradients
CGContextScaleCTM(context, 1, someSquashValue) then draw as usual with CGContextDrawRadialGradient.
CGContextDrawRadialGradient's startCenter and endCenter. Once there, you can draw a really nice radial background. 2008 05 06Core Animation's convertPoint:toLayer: and sublayerTransform
CALayer containing layers arranged in a grid, have a sublayerTransform setup on it, and want to get its transformed layer coordinates on a mouseDown, you'll need a helper layer :
// We're in mouseDown
CGPoint point = NSPointToCGPoint([self convertPoint:event.locationInWindow fromView:nil]);
// Build a dummy CALayer and insert it
CALayer* helperLayer = [CALayer layer];
[containerLayer addSublayer:helperLayer];
// Get coordinates
CGPoint layerPoint = [[self layer] convertPoint:point toLayer:helperLayer];
// Remove our helper layer
[helperLayer removeFromSuperlayer];
Now why can't we just ask for containerLayer's coordinates ? Because it has a sublayerTransform, so its coordinates are really the same as its parent. We can't ask for one of containerLayer.sublayers either : being laid out (layouted ? :) ) in a grid, they each have their own coordinate system. We therefore use a dummy layer : it has a default position of [0, 0] and will give the point transformed trough sublayerTransform. 2008 05 05ImageKit's HUD Controls1
Add Quartz.framework to your project, open your NIB, drag sliders in and set their class to IKGraySlider (top one in the screenshot) or IKSlider (bottom one). The white spinner is IKSmallProgressIndicator, it has to be setup in code.
Thanks to F-Script for the spying around. There are more classes but I can't get them to work. Also, plenty of images in /System/Library/Frameworks/Quartz.framework/Versions/A/Frameworks/ImageKit.framework/Versions/A/Resources/
Sample code
2008 05 01Changing the background color of an NSButton
NSButtons' drawRect — that's quite overkill to color just one button. :) 2008 05 01Core Animation is right handed4
For some reason I thought CA was left handed — I had my layers set with a positive Z value. The layers showed up where I was expecting them, but visually it was a mess : the far layers were drawn on top of the near layers ! Using a negative Z value fixed the glitch.
Perspective in CA, using 3D CALayers and a perspective transform :
your eye layers are closer (bigger) here layers have same size as in 2D layers are farther (smaller) here ------------------ positive Z value ------------------------- zero Z value ----------------------- negative Z value---------
2008 04 29Core Animation is mostly 2D
-
myLayer.transform = projectionTransformonlymyLayerwill have perspective, not itssublayers -
myLayer.sublayerTransform = projectionTransformonlymyLayer'ssublayerswill have perspective, notmyLayernor itssublayers'ssublayers
If you want a CALayer to have perspective and one of its sublayers to also have perspective, make sure they both have a perspective transform applied.
CALayers as if they were living in a 3D world, but Core Animation is not a mini OpenGL to handle textured rectangles. I wish it were, though.