【问题标题】:Using a view with a superlayer as a layer mask使用带有超级图层的视图作为图层蒙版
【发布时间】:2021-05-03 20:38:41
【问题描述】:

我有一个视图,我想覆盖一个透明的黑色层,其边缘与视图完全匹配。视图不会裁剪其边界,因此子视图可能会挂起。

显而易见的解决方案是CALayermask 属性,但文档说遮罩层“不能有超级层”,否则行为未定义。

我希望使用该视图的presentationLayer 是一种有效的解决方法,但我认为我不完全理解表示层是什么,因为该属性返回nil

有没有人有关于如何遮盖透明黑色图层以匹配将要绘制的视图形状的提示?谢谢。

【问题讨论】:

    标签: macos cocoa core-animation calayer nsview


    【解决方案1】:

    有一个不太明显的解决方案应该比屏蔽效果更好:混合模式过滤器,特别是source-atop。如果您将透明图层添加为它应该变暗的图层的同级,并为其分配适当的CI compositing filter,它将使这些图层变暗,而不会影响其边界之外的任何内容。作为奖励,您将在边缘获得正确的抗锯齿,这与蒙版叠加方法不同。

    这是一个例子。出于说明目的,我将调光层仅设置为它所覆盖区域高度的一半,但您当然希望将其放大。

    let container = CALayer()
    container.backgroundColor = NSColor.systemBlue.cgColor
    container.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
    
    let dimmedRoot = CALayer()
    let dimmedLayer1 = CALayer()
    dimmedLayer1.frame = CGRect(x: 20, y: 20, width: 100, height: 100)
    dimmedLayer1.backgroundColor = NSColor.systemGreen.cgColor
    dimmedLayer1.transform = CATransform3DMakeRotation(0.3, 0, 0, 1)
    
    let dimmedLayer2 = CALayer()
    dimmedLayer2.frame = CGRect(x: 80, y: 80, width: 100, height: 100)
    dimmedLayer2.backgroundColor = NSColor.systemPurple.cgColor
    dimmedLayer2.transform = CATransform3DMakeRotation(-0.1, 0, 0, 1)
    
    let dimmingLayer = CALayer()
    dimmingLayer.frame = CGRect(x: 0, y: 50, width: 200, height: 100)
    dimmingLayer.backgroundColor = NSColor(white: 0, alpha: 0.5).cgColor
    dimmingLayer.compositingFilter = CIFilter(name: "CISourceAtopCompositing")
    
    dimmedRoot.sublayers = [ dimmedLayer1, dimmedLayer2, dimmingLayer ]
    
    container.addSublayer(dimmedRoot)
    

    【讨论】:

    • Hmm.. 点击dimmingLayer,它的框架与任何兄弟相交仍然会导致其窗口接收到sendEvent 消息。你会认为这是一个错误吗?据推测,当单击透明像素时,无边框窗口不应处理事件。也许你可以提交雷达?
    • CA 的命中测试不知道合成过滤器;确定一组给定的过滤器是否最终导致透明像素是复杂且昂贵的。我认为您可以通过将 dimmingLayer 设为自定义 CALayer 子类并覆盖 containsPoint 函数以返回 false 来解决此问题。
    • 值得注意的是,在使用 compositingFilter 方法时,我仍然看到抗锯齿不匹配。至少,当暗视图是一个超椭圆时:github.com/aleclarson/react-native-super-ellipse-mask/blob/…
    猜你喜欢
    • 2018-01-25
    • 1970-01-01
    • 1970-01-01
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-25
    • 2021-08-27
    相关资源
    最近更新 更多