【问题标题】:Substract CALayer from another, blend?从另一个中减去图层,混合?
【发布时间】:2014-10-27 18:33:52
【问题描述】:

在下图中,蓝色圆圈仅用于调试目的。我的目标是蓝色圆圈后面的每一层都应该是透明的。我只想保持蓝色圆圈之外的可见。

这是用swift编写的代码:

    let croissantView = UIView(frame: CGRectMake(100, 100, 100, 100))
    croissantView.backgroundColor = UIColor.clearColor()

    self.view.addSubview(croissantView)


    let radius = 50 as CGFloat
    let width = 50 as CGFloat

    let origin = CGPointMake(0, 100)
    let end = CGPointMake(100,100)
    let highAmplitude = CGPointMake(50,180)
    let lowAmplitude = CGPointMake(50,150)

    let quad = UIBezierPath()
    quad.moveToPoint(origin)
    quad.addQuadCurveToPoint(end, controlPoint: highAmplitude)
    quad.closePath()

    let quad2 = UIBezierPath()
    quad2.moveToPoint(origin)
    quad2.addQuadCurveToPoint(end, controlPoint: lowAmplitude)
    quad2.closePath()

    let layer = CAShapeLayer()
    layer.path = quad.CGPath

    layer.strokeColor = UIColor.greenColor().CGColor
    layer.fillColor = UIColor.blackColor().CGColor

    croissantView.layer.addSublayer(layer)

    let anim =  CABasicAnimation(keyPath: "path")
    anim.duration = 3
    anim.repeatCount = 20
    anim.fromValue = quad.CGPath
    anim.toValue = quad2.CGPath
    anim.autoreverses = true
    layer.addAnimation(anim, forKey: "animQuad")


    let animRotate =  CABasicAnimation(keyPath: "transform.rotation")
    animRotate.duration = 5
    animRotate.repeatCount = 20
    animRotate.fromValue = 0
    animRotate.toValue = 360 * CGFloat(M_PI) / 180
    croissantView.layer.addAnimation(animRotate, forKey: "animRotate")


    let circle = UIBezierPath(arcCenter: croissantView.center, radius: 75, startAngle: 0, endAngle: 360 * CGFloat(M_PI) / 180, clockwise: true);
    let circleLayer = CAShapeLayer()
    circleLayer.path = circle.CGPath
    circleLayer.fillColor = UIColor.blueColor().CGColor
    circleLayer.opacity = 0.6
    self.view.layer.addSublayer(circleLayer)
想法
  • 从Layer中减去,不知道是否可行
  • 混合,不知道用CALayer怎么做

谢谢!! :)

【问题讨论】:

标签: ios swift core-graphics core-animation calayer


【解决方案1】:

我会建议三件事。

  1. 将羊角面包视图更改为图层(不确定是否有必要,但这是我所做的)

  2. 为你的圆形创建一个 CGPath,它可以反转它的掩码。你可以通过在你的圆圈周围包裹一个外部矩形来做到这一点,这样路径看起来像这样:

  1. 将圆形图层上的填充规则设置为奇偶:

    circleLayer.fillRule = kCAFillRuleEvenOdd
    

这就是它的样子:

我修改了你的代码来尝试它,这就是我想出的。您的里程可能会有所不同:

func applyMask() {

    let mainLayer = CALayer()
    mainLayer.bounds = CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)
    mainLayer.position = CGPoint(x: 200.0, y: 200.0)
    // Set the color for debugging
    mainLayer.backgroundColor = UIColor.orangeColor().CGColor

    self.view.layer.addSublayer(mainLayer)

    let radius = 50 as CGFloat
    let width = 50 as CGFloat

    let origin = CGPointMake(0, 100)
    let end = CGPointMake(100,100)
    let highAmplitude = CGPointMake(50,180)
    let lowAmplitude = CGPointMake(50,150)

    let quad = UIBezierPath()
    quad.moveToPoint(origin)
    quad.addQuadCurveToPoint(end, controlPoint: highAmplitude)
    quad.closePath()

    let quad2 = UIBezierPath()
    quad2.moveToPoint(origin)
    quad2.addQuadCurveToPoint(end, controlPoint: lowAmplitude)
    quad2.closePath()

    let layer = CAShapeLayer()
    layer.path = quad.CGPath

    layer.strokeColor = UIColor.greenColor().CGColor
    layer.fillColor = UIColor.blackColor().CGColor

    mainLayer.addSublayer(layer)

    let anim =  CABasicAnimation(keyPath: "path")
    anim.duration = 3
    anim.repeatCount = 20
    anim.fromValue = quad.CGPath
    anim.toValue = quad2.CGPath
    anim.autoreverses = true
    layer.addAnimation(anim, forKey: "animQuad")

    let animRotate =  CABasicAnimation(keyPath: "transform.rotation")
    animRotate.duration = 5
    animRotate.repeatCount = 20
    animRotate.fromValue = 0
    animRotate.toValue = 360 * CGFloat(M_PI) / 180
    mainLayer.addAnimation(animRotate, forKey: "animRotate")

    // Build a Circle CGPath
    var circlePath = CGPathCreateMutable()
    CGPathAddEllipseInRect(circlePath, nil, CGRectInset(mainLayer.bounds, -20.0, -20.0))
    // Invert the mask by adding a bounding rectangle
    CGPathAddRect(circlePath, nil, CGRectInset(mainLayer.bounds, -100.0, -100.0))
    CGPathCloseSubpath(circlePath)

    let circleLayer = CAShapeLayer()
    circleLayer.fillColor = UIColor.blueColor().CGColor
    circleLayer.opacity = 0.6
    // Use the even odd fill rule so that our path gets inverted
    circleLayer.fillRule = kCAFillRuleEvenOdd
    circleLayer.path = circlePath

    mainLayer.mask = circleLayer

    mainLayer.addSublayer(layer)
}

这是我尝试过的项目:https://github.com/perlmunger/SwiftVertedMask

希望对您有所帮助。

【讨论】:

  • 非常感谢!!它工作得很好!我会玩它以确保了解所有内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
  • 2012-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多