CALayer 过滤器覆盖其他子层

发布于 2024-10-12 07:48:29 字数 4272 浏览 8 评论 0原文

我正在开发一个信息亭类型的应用程序。我想在中间有一个徽标(可行)。现在我尝试在徽标周围添加一些浮动层。我可以绘制图层(在 drawDots 中),但是当我向其添加过滤器时 - 它会覆盖我绘制的徽标图层。我已经在这里复制了所有重要的代码。同样,如果我注释掉在 dotLayer 上设置过滤器数组的行,机器人点层的紫色方块和徽标是可见的,但是当我应用过滤器时 - 徽标不可见。我不太明白,因为我正在为这些设置正确的框架。我还尝试在 dotLayer 上使用子层做一些事情,看看是否有帮助。

- (void)awakeFromNib
{
 // Initialization code here.
 // The cursor isn't used for selection, so we hide it
 [NSCursor hide];

 // go full screen, as a kiosk application 
 [self enterFullScreenMode:[self.window screen] withOptions:NULL];

 [self setupLayers];

 [self drawDots];

 // Make the window the first responder to get keystrokes
 [self.window makeFirstResponder:self];

 // bring the window to the front
 [self.window makeKeyAndOrderFront:self];
}

- (void)drawDots
{
 CGColorRef purpleColor = CGColorCreateGenericRGB(0.604, 0.247, 0.463, 1.0);
 CGColorRef transparentColor = CGColorCreateGenericRGB(0, 0, 0, 1.0);

// CALayer *something = [CALayer layer];
// something.frame = NSMakeRect(15, 15, 60, 60); 
 CALayer *dotLayer = [CALayer layer];
 dotLayer.frame = NSMakeRect(15, 15, 30, 30);
 dotLayer.backgroundColor = purpleColor;

 CIFilter *gradientFilter = [CIFilter filterWithName:@"CIGaussianGradient"];
 [gradientFilter setDefaults];
 [gradientFilter setValue:(id)[CIColor colorWithCGColor:purpleColor] forKey:@"inputColor0"];
 [gradientFilter setValue:(id)[CIColor colorWithCGColor:transparentColor] forKey:@"inputColor1"];
 [gradientFilter setValue:(id)[NSNumber numberWithFloat:20.0] forKey:@"inputRadius"];

// dotLayer.compositingFilter = gradientFilter;

 dotLayer.filters = [NSArray arrayWithObject:(id)gradientFilter];

 [rootLayer addSublayer:dotLayer];
// [dotLayer addSublayer:something];
// 
// [rootLayer addSublayer:dotLayer];
}

- (void)setupLayers
{
 // Setup vars
 CGFloat mirroredOffset = 10.0f;

 CGColorRef blackColor = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1.0);
 CGColorRef transparentColor = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 0.0);

 // Get the image
 logo = [NSImage imageNamed:@"logo_300.png"]; 

 // Get the positioning of the logo - middle of the screen
 CGFloat logoWidth = [logo size].width;
 CGFloat logoHeight = [logo size].height;

 CGFloat imageX = [self frame].size.width / 2 - logoWidth / 2;
 CGFloat imageY = [self frame].size.height / 2 - logoHeight / 2;

 // Create the layer for the all content to be drawn on
 rootLayer = [CALayer layer];
 rootLayer.geometryFlipped = YES;
 rootLayer.opaque = YES;
 rootLayer.frame = [self frame];
 rootLayer.backgroundColor = blackColor;
 [self setLayer:rootLayer];

 NSRect imageRect = NSMakeRect(imageX, imageY, logoWidth, logoHeight * 2 + mirroredOffset);

 // Create the layer that holds the logo
 CALayer *logoLayer = [CALayer layer]; 
 logoLayer.frame = NSMakeRect(imageX, imageY, logoWidth, logoHeight);

 [rootLayer addSublayer:logoLayer];

 // Create the layer for the main logo
 CALayer *mainLogo = [CALayer layer];
 mainLogo.frame = NSMakeRect(0, 0, logoWidth, logoHeight);
 mainLogo.contents = logo;

 [logoLayer addSublayer:mainLogo];

 // Create the mirrored layer
 CALayer *logoMirroredLayer = [CALayer layer];
 logoMirroredLayer.frame = NSMakeRect(0, logoHeight + mirroredOffset, logoWidth, logoHeight);

 [logoLayer addSublayer:logoMirroredLayer];

 // Create the layer for the logo
 CALayer *logoBase  = [CALayer layer];
 logoBase.frame = NSMakeRect(0, 0, logoWidth, logoHeight);
 logoBase.contents = logo;

 [logoMirroredLayer addSublayer:logoBase];

 // Create the gradient to make the mirrored effect
 CAGradientLayer *gradientCover = [CAGradientLayer layer];
 gradientCover.frame = NSMakeRect(0, 0, imageRect.size.width, imageRect.size.height);
 gradientCover.colors = [NSArray arrayWithObjects:(id)blackColor, (id)transparentColor, nil];
 gradientCover.locations = [NSArray arrayWithObjects:(id)[NSNumber numberWithFloat:0.0f], (id)[NSNumber numberWithFloat:1.0f], nil];

 [logoMirroredLayer addSublayer:gradientCover];

 // Flip the mirrored layer
 CGAffineTransform rotateTransform = CGAffineTransformRotate(CGAffineTransformIdentity, 180.0f * M_PI / 180 );
 [logoMirroredLayer setAffineTransform:rotateTransform];

 // Make the mirrored layer see through
 logoMirroredLayer.opacity = 0.3f;

 [self setWantsLayer:YES];
}


@end

我不明白的是,其他子层是在此层之前添加的,并且该层的框架不覆盖显示徽标的位置。

I am working on a kiosk type application. I want to have a logo in the middle ( which works ). Now I'm trying to add some floating layers around the logo. I can draw the layer ( in drawDots ), but when I add a filter to it - it covers up the logo layers that I drew. I've copied all the important code here. Again, if I comment out the line that sets the filters array on the dotLayer, bot the purple square for the dot layer and the logo are visible, but when I apply the filter - the logo is not visible. I don't really understand since I am setting what should be the proper frames on these. I also tried to do something with a sublayer on the dotLayer to see if that would help.

- (void)awakeFromNib
{
 // Initialization code here.
 // The cursor isn't used for selection, so we hide it
 [NSCursor hide];

 // go full screen, as a kiosk application 
 [self enterFullScreenMode:[self.window screen] withOptions:NULL];

 [self setupLayers];

 [self drawDots];

 // Make the window the first responder to get keystrokes
 [self.window makeFirstResponder:self];

 // bring the window to the front
 [self.window makeKeyAndOrderFront:self];
}

- (void)drawDots
{
 CGColorRef purpleColor = CGColorCreateGenericRGB(0.604, 0.247, 0.463, 1.0);
 CGColorRef transparentColor = CGColorCreateGenericRGB(0, 0, 0, 1.0);

// CALayer *something = [CALayer layer];
// something.frame = NSMakeRect(15, 15, 60, 60); 
 CALayer *dotLayer = [CALayer layer];
 dotLayer.frame = NSMakeRect(15, 15, 30, 30);
 dotLayer.backgroundColor = purpleColor;

 CIFilter *gradientFilter = [CIFilter filterWithName:@"CIGaussianGradient"];
 [gradientFilter setDefaults];
 [gradientFilter setValue:(id)[CIColor colorWithCGColor:purpleColor] forKey:@"inputColor0"];
 [gradientFilter setValue:(id)[CIColor colorWithCGColor:transparentColor] forKey:@"inputColor1"];
 [gradientFilter setValue:(id)[NSNumber numberWithFloat:20.0] forKey:@"inputRadius"];

// dotLayer.compositingFilter = gradientFilter;

 dotLayer.filters = [NSArray arrayWithObject:(id)gradientFilter];

 [rootLayer addSublayer:dotLayer];
// [dotLayer addSublayer:something];
// 
// [rootLayer addSublayer:dotLayer];
}

- (void)setupLayers
{
 // Setup vars
 CGFloat mirroredOffset = 10.0f;

 CGColorRef blackColor = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1.0);
 CGColorRef transparentColor = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 0.0);

 // Get the image
 logo = [NSImage imageNamed:@"logo_300.png"]; 

 // Get the positioning of the logo - middle of the screen
 CGFloat logoWidth = [logo size].width;
 CGFloat logoHeight = [logo size].height;

 CGFloat imageX = [self frame].size.width / 2 - logoWidth / 2;
 CGFloat imageY = [self frame].size.height / 2 - logoHeight / 2;

 // Create the layer for the all content to be drawn on
 rootLayer = [CALayer layer];
 rootLayer.geometryFlipped = YES;
 rootLayer.opaque = YES;
 rootLayer.frame = [self frame];
 rootLayer.backgroundColor = blackColor;
 [self setLayer:rootLayer];

 NSRect imageRect = NSMakeRect(imageX, imageY, logoWidth, logoHeight * 2 + mirroredOffset);

 // Create the layer that holds the logo
 CALayer *logoLayer = [CALayer layer]; 
 logoLayer.frame = NSMakeRect(imageX, imageY, logoWidth, logoHeight);

 [rootLayer addSublayer:logoLayer];

 // Create the layer for the main logo
 CALayer *mainLogo = [CALayer layer];
 mainLogo.frame = NSMakeRect(0, 0, logoWidth, logoHeight);
 mainLogo.contents = logo;

 [logoLayer addSublayer:mainLogo];

 // Create the mirrored layer
 CALayer *logoMirroredLayer = [CALayer layer];
 logoMirroredLayer.frame = NSMakeRect(0, logoHeight + mirroredOffset, logoWidth, logoHeight);

 [logoLayer addSublayer:logoMirroredLayer];

 // Create the layer for the logo
 CALayer *logoBase  = [CALayer layer];
 logoBase.frame = NSMakeRect(0, 0, logoWidth, logoHeight);
 logoBase.contents = logo;

 [logoMirroredLayer addSublayer:logoBase];

 // Create the gradient to make the mirrored effect
 CAGradientLayer *gradientCover = [CAGradientLayer layer];
 gradientCover.frame = NSMakeRect(0, 0, imageRect.size.width, imageRect.size.height);
 gradientCover.colors = [NSArray arrayWithObjects:(id)blackColor, (id)transparentColor, nil];
 gradientCover.locations = [NSArray arrayWithObjects:(id)[NSNumber numberWithFloat:0.0f], (id)[NSNumber numberWithFloat:1.0f], nil];

 [logoMirroredLayer addSublayer:gradientCover];

 // Flip the mirrored layer
 CGAffineTransform rotateTransform = CGAffineTransformRotate(CGAffineTransformIdentity, 180.0f * M_PI / 180 );
 [logoMirroredLayer setAffineTransform:rotateTransform];

 // Make the mirrored layer see through
 logoMirroredLayer.opacity = 0.3f;

 [self setWantsLayer:YES];
}


@end

What I don't understand is that the other sub-layers are added before this one and the frame for this layer doesn't cover where the logo is displayed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请爱~陌生人 2024-10-19 07:48:29

你的 CALayer 的 mask 是什么样的? CIFilter 可能会将您的 Alpha 通道设置为非零,从而遮挡其后面的图层。

What does your CALayer's mask look like? The CIFilter could be setting your alpha channel to non-zero thus occluding the layers behind it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文