Path-based 面具很好anti-aliasing
Path-based mask with nice anti-aliasing
我想用圆圈遮盖正方形。我正在使用它而不是角半径,因为我想稍后用动画做一些事情。
我可以把它遮起来,但是边缘很粗糙:
// Target View
let targetView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
targetView.backgroundColor = UIColor.redColor()
// Mask
let maskingPath = UIBezierPath()
let half = targetView.frame.width / 2
maskingPath.addArcWithCenter(CGPoint(x: half, y: half), radius: half, startAngle: 0, endAngle: 360, clockwise: true)
let maskingLayer = CAShapeLayer()
maskingLayer.path = maskingPath.CGPath
// Maybe setting contentsScale?
// maskingLayer.contentsScale = UIScreen.mainScreen().scale // doesn't change anything, sorry
// Maybe enabling edgeAntialiasing?
// maskingLayer.allowsEdgeAntialiasing = true // also doesn't change anything
// Magnification filter?
// maskingLayer.magnificationFilter = kCAFilterNearest // nuttin'
targetView.layer.mask = maskingLayer
我已经尝试了 magnificationFilter 和其他一些东西。
如何添加抗锯齿的可动画圆形遮罩?
找到解决方案,但未找到根本原因。
这样会画脆:
let maskingPath = UIBezierPath()
let half = targetView.frame.width / 2
maskingPath.addArcWithCenter(CGPoint(x: half, y: half), radius: half, startAngle: 0, endAngle: 360, clockwise: true)
let maskingLayer = CAShapeLayer()
maskingLayer.path = maskingPath.CGPath
targetView.layer.mask = maskingLayer
这会画得很好并且抗锯齿:
let maskingLayer = CAShapeLayer()
maskingLayer.path = UIBezierPath(ovalInRect: targetView.bounds).CGPath
targetView.layer.mask = maskingLayer
希望我知道为什么。它们都 CGPath
用作图层蒙版。
编辑:Kurt 指出我正在绘制 360
弧度,这就像一遍又一遍地绘制同一个圆圈,看起来不透明并且破坏了正在发生的任何抗锯齿。
您给 addArcWithCenter
一个角度(以度为单位):
maskingPath.addArcWithCenter(CGPoint(x: half, y: half),
radius: half,
startAngle: 0,
endAngle: 360,
clockwise: true)
但 the documentation 声明角度应以弧度为单位。
因此,您正在创建一条自身重叠多次的路径。边缘绘制在边缘先前通过的顶部,在同一位置。在积累足够多的通道后,它们最终看起来不透明(或几乎不透明)。如果您在彼此之上创建多个圆形路径,您会看到类似的东西。
这对我来说效果更好:
maskingPath.addArcWithCenter(CGPoint(x: half, y: half),
radius: half,
startAngle: 0,
endAngle: CGFloat(M_PI * 2.0),
clockwise: true)
(但由于您真的想要一个封闭的椭圆,您应该像您在回答中所做的那样使用 UIBezierPath(ovalInRect: targetView.bounds)
。)
我想用圆圈遮盖正方形。我正在使用它而不是角半径,因为我想稍后用动画做一些事情。
我可以把它遮起来,但是边缘很粗糙:
// Target View
let targetView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
targetView.backgroundColor = UIColor.redColor()
// Mask
let maskingPath = UIBezierPath()
let half = targetView.frame.width / 2
maskingPath.addArcWithCenter(CGPoint(x: half, y: half), radius: half, startAngle: 0, endAngle: 360, clockwise: true)
let maskingLayer = CAShapeLayer()
maskingLayer.path = maskingPath.CGPath
// Maybe setting contentsScale?
// maskingLayer.contentsScale = UIScreen.mainScreen().scale // doesn't change anything, sorry
// Maybe enabling edgeAntialiasing?
// maskingLayer.allowsEdgeAntialiasing = true // also doesn't change anything
// Magnification filter?
// maskingLayer.magnificationFilter = kCAFilterNearest // nuttin'
targetView.layer.mask = maskingLayer
我已经尝试了 magnificationFilter 和其他一些东西。
如何添加抗锯齿的可动画圆形遮罩?
找到解决方案,但未找到根本原因。
这样会画脆:
let maskingPath = UIBezierPath()
let half = targetView.frame.width / 2
maskingPath.addArcWithCenter(CGPoint(x: half, y: half), radius: half, startAngle: 0, endAngle: 360, clockwise: true)
let maskingLayer = CAShapeLayer()
maskingLayer.path = maskingPath.CGPath
targetView.layer.mask = maskingLayer
这会画得很好并且抗锯齿:
let maskingLayer = CAShapeLayer()
maskingLayer.path = UIBezierPath(ovalInRect: targetView.bounds).CGPath
targetView.layer.mask = maskingLayer
希望我知道为什么。它们都 CGPath
用作图层蒙版。
编辑:Kurt 指出我正在绘制 360
弧度,这就像一遍又一遍地绘制同一个圆圈,看起来不透明并且破坏了正在发生的任何抗锯齿。
您给 addArcWithCenter
一个角度(以度为单位):
maskingPath.addArcWithCenter(CGPoint(x: half, y: half),
radius: half,
startAngle: 0,
endAngle: 360,
clockwise: true)
但 the documentation 声明角度应以弧度为单位。
因此,您正在创建一条自身重叠多次的路径。边缘绘制在边缘先前通过的顶部,在同一位置。在积累足够多的通道后,它们最终看起来不透明(或几乎不透明)。如果您在彼此之上创建多个圆形路径,您会看到类似的东西。
这对我来说效果更好:
maskingPath.addArcWithCenter(CGPoint(x: half, y: half),
radius: half,
startAngle: 0,
endAngle: CGFloat(M_PI * 2.0),
clockwise: true)
(但由于您真的想要一个封闭的椭圆,您应该像您在回答中所做的那样使用 UIBezierPath(ovalInRect: targetView.bounds)
。)