我正在尝试画一个相当基本的鸟形状。我使用圆圈作为身体,并尝试绘制上喙(以红色突出显示),如下面的参考图所示。
图片参考:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
我想要实现的目标是让喙也沿着身体圆的圆周以弧线关闭,以便我可以稍后通过旋转对其进行动画处理以模拟喙打开/关闭。任何帮助表示赞赏。
如果您用来.addArc绘制弯曲的位,那么就没什么了不起的。如果您使用中点作为圆弧的起点,然后使用 将最终形状移动到位,这可能会更容易.offset。这也为后面添加旋转效果做好了准备。
为了将鸟头的特征保持在一起,您可以将它们全部作为叠加层应用到基圆上,也可以将它们构建在单独的ZStack. 单独进行ZStack可能更简单,框架尺寸ZStack可用于确定圆圈以及眼睛和喙的尺寸。
这是改编后的Shape:
struct Beak: Shape {
let angleDegrees: CGFloat
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: rect.midX, y: rect.midY))
path.addArc(
center: CGPoint(x: rect.maxX, y: rect.midY),
radius: rect.midX,
startAngle: .degrees(180),
endAngle: .degrees(180 + angleDegrees),
clockwise: angleDegrees < 0
)
path.addLine(to: CGPoint(x: 0, y: rect.midY))
path.closeSubpath()
return path
}
}
Run Code Online (Sandbox Code Playgroud)
以下是如何使用它。我无法抗拒将其动画化
struct BirdView: View {
@State private var gapeAngle = Angle.zero
private func birdHead(diameter: CGFloat) -> some View {
ZStack {
Circle()
.fill(.yellow)
Circle()
.stroke(lineWidth: 5)
// Eye
Ellipse()
.fill(.black)
.frame(width: diameter / 5, height: diameter / 5.55)
.offset(x: -diameter / 4.7, y: -diameter / 5.35)
// Upper beak
Beak(angleDegrees: 20)
.stroke(style: .init(lineWidth: 5, lineJoin: .round))
.foregroundStyle(.red)
.offset(x: -diameter / 2)
.rotationEffect(gapeAngle)
// Lower beak
Beak(angleDegrees: -20)
.stroke(style: .init(lineWidth: 5, lineJoin: .round))
.foregroundStyle(.red)
.offset(x: -diameter / 2)
.rotationEffect(-gapeAngle)
}
.frame(width: diameter, height: diameter)
}
var body: some View {
birdHead(diameter: 150)
.padding(.leading, 50)
.frame(width: 300, height: 300)
.background(.orange)
.onAppear {
withAnimation(.easeInOut.repeatForever(autoreverses: true)) {
gapeAngle = .degrees(5)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)

| 归档时间: |
|
| 查看次数: |
118 次 |
| 最近记录: |