You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中绘制带角度线条与圆弧:实现可动画鸟喙

SwiftUI实现贴合鸟身圆周的可动画鸟喙

问题说明

需求是用SwiftUI绘制鸟类图形,以Circle作为鸟身,实现贴合鸟身圆周的上喙(参考红色高亮样式),并支持动画模拟鸟喙开合。

解决方案代码

可动画的鸟喙Shape

struct Beak: Shape {
    // 控制鸟喙开合角度,0为闭合,数值越大张开幅度越大
    var openAngle: Double = 0
    
    // 让角度参数支持SwiftUI动画
    var animatableData: Double {
        get { openAngle }
        set { openAngle = newValue }
    }
    
    func path(in rect: CGRect) -> Path {
        var path = Path()
        
        // 对齐鸟身的圆心和半径
        let bodyCenter = CGPoint(x: rect.width, y: rect.height / 2)
        let bodyRadius = rect.width / 2
        
        // 计算鸟身与鸟喙连接的两个端点
        let startAngle = Angle(degrees: 180 + openAngle)
        let startPoint = CGPoint(
            x: bodyCenter.x + bodyRadius * cos(startAngle.radians),
            y: bodyCenter.y + bodyRadius * sin(startAngle.radians)
        )
        
        let endAngle = Angle(degrees: 180 - openAngle)
        let endPoint = CGPoint(
            x: bodyCenter.x + bodyRadius * cos(endAngle.radians),
            y: bodyCenter.y + bodyRadius * sin(endAngle.radians)
        )
        
        // 绘制鸟喙路径:连接点 → 尖端 → 连接点 → 沿鸟身圆弧闭合
        path.move(to: startPoint)
        path.addLine(to: CGPoint(x: 0, y: rect.height / 2))
        path.addLine(to: endPoint)
        path.addArc(
            center: bodyCenter,
            radius: bodyRadius,
            startAngle: endAngle,
            endAngle: startAngle,
            clockwise: true
        )
        
        return path
    }
}

鸟类视图及动画实现

struct BirdView: View {
    @State private var isBeakOpen = false
    
    var body: some View {
        ZStack {
            // 鸟身
            Circle()
                .stroke(lineWidth: 10)
                .frame(width: 150)
                .overlay {
                    Circle().fill(.yellow)
                }
            
            // 鸟喙:尺寸与鸟身对齐,添加开合动画
            Beak(openAngle: isBeakOpen ? 15 : 0)
                .fill(.black)
                .frame(width: 75, height: 150) // 宽度为鸟身半径,高度匹配鸟身
                .offset(x: -75) // 偏移对齐鸟身圆心
        }
        .frame(width: 300, height: 300)
        .background(.orange)
        .onTapGesture {
            // 点击触发开合动画
            withAnimation(.easeInOut(duration: 0.3)) {
                isBeakOpen.toggle()
            }
        }
    }
}

关键说明

  • 动画支持:通过animatableData将openAngle设为可动画参数,实现开合的平滑过渡
  • 贴合鸟身:统一鸟喙和鸟身的圆心、半径,用三角函数计算连接点,确保鸟喙边缘完美贴合鸟身圆周
  • 灵活调整:修改openAngle的最大值(示例中为15度)可调整鸟喙张开幅度,点击手势可替换为其他触发逻辑

内容的提问来源于stack exchange,提问作者batman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:51:06