I’m trying to draw a fairly basic bird shape. I’m using the circle for the body and I’m trying to draw the upper beak (highlighted in red) like shown in the reference image below.
Image reference:
struct Beak: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: rect.width/4, y: rect.height/2))
path.addLine(to: CGPoint(x: 0, y: rect.height/2))
// draw a line back to the circumference at a given angle
// & close it with an arc along the circumference of the Body circle
path.addLine(to: ??)
return path
}
}
struct BirdView: View {
var body: some View {
ZStack {
// MARK: Body
Circle()
.stroke(lineWidth: 10)
.frame(width: 150)
.overlay(alignment: .center) {
Circle()
.fill(.yellow)
}
// MARK: Beak
Beak()
.stroke(lineWidth: 5)
}
.frame(width: 300, height: 300)
.background(.orange)
}
}
What I’m trying to achieve is for the beak to also close with an arc along the circumference of the body circle so that I can animate it later with rotation to simulate the beak open/close. Any help is appreciated.
2
Answers
Instead of doing the math to figure out how to draw the arc, I would just use
subtracting
to "subtract" the circle from a right-angled triangle.Then the beak and body can be combined like this:
Notes:
.round
line join to stroke the beak, because a miter join looks terribleOutput:
If you use
.addArc
to draw the curved bit then there’s not much to it. It’s perhaps easier if you use the middle point for the start of the arc and then move the final shape into position using.offset
. Also, if you apply it as an overlay to theCircle
then you can base the size of the beak on the size of the circle.Here’s the adapted
Shape
:And here’s how you can use it. I couldn’t resist animating itπ