使用 CAShapeLayer 动画部分蒙版的透明度
Animate transparency of part of mask with CAShapeLayer
我对.brown
backgroundColor
有看法。
在那个视图中我有一个 backgroundView
,它有 backgroundColor: UIColor.black.withAlphaComponent(0.5)
。
然后我想在这个 backgroundView
中有一个透明框来显示底层视图。我已经实现了这一点,但是我不能通过动画化它的透明度来做到这一点,我的代码只增加 "cut out area" 直到所需的大小而不是动画化它的透明度。
带有 backgroundView 的棕色视图,它是 0.5 alpha
添加图层到 backgroundView 显示部分棕色视图
我编写的代码是这样的:
func addIndicatorTo(global frame: CGRect) {
let shape = CAShapeLayer()
let targetRect = convert(frame, from: nil).insetBy(dx: -4, dy: -4)
let animation = CABasicAnimation(keyPath: "path")
let toPath = CGMutablePath()
toPath.addRect(bounds)
toPath.addPath(UIBezierPath(roundedRect: targetRect,
byRoundingCorners: .allCorners,
cornerRadii: CGSize(width: 4, height: 4)).cgPath)
toPath.closeSubpath()
let fromPath = CGMutablePath()
fromPath.addRect(bounds)
fromPath.addPath(UIBezierPath(roundedRect: targetRect.insetBy(dx: targetRect.width / 2,
dy: targetRect.height / 2),
byRoundingCorners: .allCorners,
cornerRadii: CGSize(width: 4, height: 4)).cgPath)
fromPath.closeSubpath()
animation.fromValue = fromPath
animation.toValue = toPath
animation.duration = 0.5
shape.fillRule = .evenOdd
shape.path = animation.fromValue as! CGPath
backgroundView.layer.mask = shape
shape.add(animation, forKey: nil)
CATransaction.begin()
CATransaction.setDisableActions(true)
shape.path = toPath
CATransaction.commit()
}
不确定这是否是 "good" 解决方案。但我会坚持下去,直到有人告诉我如何更优雅地解决它!
基本上,我只是创建了一个蒙版并切掉了方框,然后我创建了一个新的 boxLayer
,在 "cutout" 的区域绘制。然后我只是为 boxLayer
的 opacity
设置动画。
func addIndicatorTo(global frame: CGRect) {
let maskLayer = CAShapeLayer()
let boxLayer = CAShapeLayer()
let targetRect = convert(frame, from: nil).insetBy(dx: -4, dy: -4)
let animation = CABasicAnimation(keyPath: "opacity")
let toPath = CGMutablePath()
let boxPath = UIBezierPath(roundedRect: targetRect,
byRoundingCorners: .allCorners,
cornerRadii: CGSize(width: 4, height: 4)).cgPath
toPath.addRect(bounds)
toPath.addPath(boxPath)
toPath.closeSubpath()
boxLayer.fillColor = UIColor.black.withAlphaComponent(0.5).cgColor
boxLayer.path = boxPath
animation.fromValue = 1.0
animation.toValue = 0.0
animation.duration = 0.5
maskLayer.fillRule = .evenOdd
maskLayer.path = toPath
backgroundView.layer.mask = maskLayer
layer.addSublayer(boxLayer)
boxLayer.add(animation, forKey: nil)
CATransaction.begin()
CATransaction.setDisableActions(true)
boxLayer.opacity = 0.0
CATransaction.commit()
}
我对.brown
backgroundColor
有看法。
在那个视图中我有一个 backgroundView
,它有 backgroundColor: UIColor.black.withAlphaComponent(0.5)
。
然后我想在这个 backgroundView
中有一个透明框来显示底层视图。我已经实现了这一点,但是我不能通过动画化它的透明度来做到这一点,我的代码只增加 "cut out area" 直到所需的大小而不是动画化它的透明度。
带有 backgroundView 的棕色视图,它是 0.5 alpha
添加图层到 backgroundView 显示部分棕色视图
我编写的代码是这样的:
func addIndicatorTo(global frame: CGRect) {
let shape = CAShapeLayer()
let targetRect = convert(frame, from: nil).insetBy(dx: -4, dy: -4)
let animation = CABasicAnimation(keyPath: "path")
let toPath = CGMutablePath()
toPath.addRect(bounds)
toPath.addPath(UIBezierPath(roundedRect: targetRect,
byRoundingCorners: .allCorners,
cornerRadii: CGSize(width: 4, height: 4)).cgPath)
toPath.closeSubpath()
let fromPath = CGMutablePath()
fromPath.addRect(bounds)
fromPath.addPath(UIBezierPath(roundedRect: targetRect.insetBy(dx: targetRect.width / 2,
dy: targetRect.height / 2),
byRoundingCorners: .allCorners,
cornerRadii: CGSize(width: 4, height: 4)).cgPath)
fromPath.closeSubpath()
animation.fromValue = fromPath
animation.toValue = toPath
animation.duration = 0.5
shape.fillRule = .evenOdd
shape.path = animation.fromValue as! CGPath
backgroundView.layer.mask = shape
shape.add(animation, forKey: nil)
CATransaction.begin()
CATransaction.setDisableActions(true)
shape.path = toPath
CATransaction.commit()
}
不确定这是否是 "good" 解决方案。但我会坚持下去,直到有人告诉我如何更优雅地解决它!
基本上,我只是创建了一个蒙版并切掉了方框,然后我创建了一个新的 boxLayer
,在 "cutout" 的区域绘制。然后我只是为 boxLayer
的 opacity
设置动画。
func addIndicatorTo(global frame: CGRect) {
let maskLayer = CAShapeLayer()
let boxLayer = CAShapeLayer()
let targetRect = convert(frame, from: nil).insetBy(dx: -4, dy: -4)
let animation = CABasicAnimation(keyPath: "opacity")
let toPath = CGMutablePath()
let boxPath = UIBezierPath(roundedRect: targetRect,
byRoundingCorners: .allCorners,
cornerRadii: CGSize(width: 4, height: 4)).cgPath
toPath.addRect(bounds)
toPath.addPath(boxPath)
toPath.closeSubpath()
boxLayer.fillColor = UIColor.black.withAlphaComponent(0.5).cgColor
boxLayer.path = boxPath
animation.fromValue = 1.0
animation.toValue = 0.0
animation.duration = 0.5
maskLayer.fillRule = .evenOdd
maskLayer.path = toPath
backgroundView.layer.mask = maskLayer
layer.addSublayer(boxLayer)
boxLayer.add(animation, forKey: nil)
CATransaction.begin()
CATransaction.setDisableActions(true)
boxLayer.opacity = 0.0
CATransaction.commit()
}