-
Notifications
You must be signed in to change notification settings - Fork 18
ShapeLayer's geometry semantics are weird #89
Comments
I think I’m a little clear on the implications of this. What does this mean practically? |
Practically, this would mean that
|
Aha, this is the surprising thing. Why is the CAShapeLayer’s anchorPoint non-default here? |
Ah, because we need the layer's transform to operate about the path's center, not the layer's center.
|
Hmmm, I thought the intention was to keep the layer’s geometry in sync with the path’s geometry? |
Well, my plan was to let the public class ShapeLayer {
// position and anchorPoint are not overridden
public var segments: [Segment] {
set {
_segments = newValue.map { (var segment) in
segment.point -= self.position
return segment
}
}
get {
return _segments.map { (var segment) in
segment.point += self.position
return segment
}
}
}
private var _segments: [Segment] {
didSet {
layer.path = computePathFromSegments(_segments)
}
}
public override var bounds: Rect {
get {
return Rect(origin: super.bounds.origin, size: Size(CGPathGetPathBoundingBox(layer.path).size))
}
set {
precondition(newValue.size == super.bounds.size)
super.bounds.origin = newValue.origin
}
}
public override var frame: Rect {
get {
var bounds = Rect(CGPathGetPathBoundingBox(layer.path))
var frame = /* apply layer.transform to bounds */
frame.origin += position
return frame
}
set {
precondition(newValue.size == super.frame.size)
position += /* transform (newValue.origin - frame.origin) by layer.transform */
}
}
} |
Yeah this seems about right to me. |
ShapeLayer
is built onCAShapeLayer
, from which it inherits an odd API detail: the geometry of the layer is distinct from the geometry of the path.That is to say: if I make a shape layer and add two segments at (0, 0) and (100, 100), the bounds of the layer is unaffected by those segments' positions. Changing the layer's position doesn't change the segments' position and vice-versa. Hit testing in particular becomes a very weird thing!
I propose:
ShapeLayer.position { get }
returnspath.bounds
atShapeLayer.anchorPoint
.ShapeLayer.anchorPoint
operates relative topath
, not the full bounds of the layer.segments
changesLayer.anchorPoint
so that it reflectsShapeLayer.anchorPoint
relative to the new path's bounds.ShapeLayer.position { set }
addsnewValue
's delta to each segment's points.ShapeLayer.bounds { get }
returnspath.bounds
.ShapeLayer.frame { get }
transforms theposition
andbounds
overrides described above, notLayer
's implementations.ShapeLayer.frame { set }
andShapeLayer.bounds { set }
throw an exception if thesize
of the newRect
is different from the current one.Segment coordinates are specified in the
ShapeLayer
's superlayer's coordinate space.The text was updated successfully, but these errors were encountered: