ant*_*ons 7 core-animation core-graphics objective-c
我想掩盖一个CALayerwith CAShapeLayer,因为形状的变化可以动画.
当我使用它CAShapeLayer作为面具时,圆角被拉伸.但是,如果我采用相同的形状,NSImage使用它创建一个,并使用图像来掩盖我的CALayer,圆角是完美的.

这是我用来掩盖图层的代码(你也可以下载整个示例项目):
CGColorRef backgroundColor = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1.0f);
[self.window.contentView setLayer:[CALayer layer]];
[self.window.contentView setWantsLayer:YES];
[[self.window.contentView layer] setFrame:[self.window.contentView frame]];
CALayer *imageBasedMaskLayer = [CALayer layer];
[imageBasedMaskLayer setContents:(id)[[self maskWithSize:NSMakeSize(50, 50)] CGImageForProposedRect:NULL context:nil hints:nil]];
[imageBasedMaskLayer setFrame:CGRectMake(0, 0, 50, 50)];
CALayer *layerWithImageBasedMaskLayer = [CALayer layer];
[layerWithImageBasedMaskLayer setBackgroundColor:backgroundColor];
[layerWithImageBasedMaskLayer setMask:imageBasedMaskLayer];
CAShapeLayer *shapeBasedMaskLayer = [CAShapeLayer layer];
CGPathRef maskShape = [self newMaskPathWithFrame:NSMakeRect(0, 0, 50, 50)];
[shapeBasedMaskLayer setPath:maskShape];
[shapeBasedMaskLayer setFillRule:kCAFillRuleEvenOdd];
CGPathRelease(maskShape);
[shapeBasedMaskLayer setFrame:CGRectMake(0, 0, 50, 50)];
CALayer *layerWithShapeBasedMaskLayer = [CALayer layer];
[layerWithShapeBasedMaskLayer setBackgroundColor:backgroundColor];
[layerWithShapeBasedMaskLayer setMask:nil];
[layerWithShapeBasedMaskLayer setMask:shapeBasedMaskLayer];
[layerWithImageBasedMaskLayer setFrame:CGRectMake(50, 50, 50, 50)];
[layerWithShapeBasedMaskLayer setFrame:CGRectMake(120, 50, 50, 50)];
[[self.window.contentView layer] addSublayer:layerWithImageBasedMaskLayer];
[[self.window.contentView layer] addSublayer:layerWithShapeBasedMaskLayer];
CGColorRelease(backgroundColor);
Run Code Online (Sandbox Code Playgroud)
而且,这两个方法,我使用的是创建NSImage和CGPathRef.
- (NSImage *)maskWithSize:(CGSize)size;
{
NSImage *maskImage = [[NSImage alloc] initWithSize:size];
[maskImage lockFocus];
[[NSColor blackColor] setFill];
CGPathRef mask = [self newMaskPathWithFrame:CGRectMake(0, 0, size.width, size.height)];
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
CGContextAddPath(context, mask);
CGContextFillPath(context);
CGPathRelease(mask);
[maskImage unlockFocus];
return [maskImage autorelease];
}
- (CGPathRef)newMaskPathWithFrame:(CGRect)frame;
{
CGFloat cornerRadius = 3;
CGFloat height = CGRectGetMaxY(frame);
CGFloat width = CGRectGetMaxX(frame);
CGMutablePathRef maskPath = CGPathCreateMutable();
CGPathMoveToPoint(maskPath, NULL, 0, height-cornerRadius);
CGPathAddArcToPoint(maskPath, NULL, 0, height, cornerRadius, height, cornerRadius);
CGPathAddLineToPoint(maskPath, NULL, width-cornerRadius, height);
CGPathAddArcToPoint(maskPath, NULL, width, height, width, height-cornerRadius, cornerRadius);
CGPathAddLineToPoint(maskPath, NULL, width, cornerRadius);
CGPathAddArcToPoint(maskPath, NULL, width, 0, width-cornerRadius, 0, cornerRadius);
CGPathAddLineToPoint(maskPath, NULL, cornerRadius, 0);
CGPathAddArcToPoint(maskPath, NULL, 0, 0, 0, cornerRadius, cornerRadius);
CGPathCloseSubpath(maskPath);
return maskPath;
}
Run Code Online (Sandbox Code Playgroud)
请注意,我想要创建的实际蒙版比圆角矩形更复杂,否则我会使用一些更简单的绘图技术.我尝试了各种CGPath绘图功能,问题并没有消失.
我在这里错过了什么?
那是因为CAShapeLayer速度比准确性更重要。这就是为什么有时它可能会关闭。
形状将被抗锯齿绘制,并且只要有可能,它就会在光栅化之前映射到屏幕空间以保持分辨率独立性。但是,应用于图层或其祖先的某些类型的图像处理操作(例如 CoreImage 滤镜)可能会强制在局部坐标空间中进行光栅化。
注意:形状光栅化可能有利于速度而不是精度。例如,具有多个相交路径段的像素可能无法给出准确的结果。
你可以使用
layerWithShapeBasedMaskLayer.cornerRadius = 3.0;
Run Code Online (Sandbox Code Playgroud)
圆润你的所有角落。你不再需要了CAShapeLayer。您甚至可以继续使用您的CAShapeLayer子图层来对路径进行动画处理。刚刚设置
layerWithShapeBasedMaskLayer.masksToBounds = YES;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3479 次 |
| 最近记录: |