我试着画出这只飞快的鸟,画出了下面的形状.

struct SwiftBird: Shape {
    func path(in rect: CGRect) -> Path {
        let size = min(rect.width, rect.height)

        let path = Path { path in
            path.move(to: CGPoint(x: 0.565 * size, y: 0.145 * size))
            path.addQuadCurve(to: CGPoint(x: 0.79 * size, y: 0.62 * size), control: CGPointMake(0.85 * size, 0.34 * size))
            
            path.move(to: CGPoint(x: 0.79 * size, y: 0.62 * size))
            path.addQuadCurve(to: CGPoint(x: 0.845 * size, y: 0.825 * size), control: CGPointMake(0.88 * size, 0.75 * size))
            
            path.move(to: CGPoint(x: 0.1 * size, y: 0.58 * size))
            path.addQuadCurve(to: CGPoint(x: 0.5 * size, y: 0.82 * size), control: CGPointMake(0.25 * size, 0.8 * size))
            path.addQuadCurve(to: CGPoint(x: 0.67 * size, y: 0.775 * size), control: CGPointMake(0.6 * size, 0.82 * size))
            path.addQuadCurve(to: CGPoint(x: 0.845 * size, y: 0.825 * size), control: CGPointMake(0.78 * size, 0.715 * size))
            
            path.move(to: CGPoint(x: 0.1 * size, y: 0.58 * size))
            path.addQuadCurve(to: CGPoint(x: 0.525 * size, y: 0.63 * size), control: CGPointMake(0.325 * size, 0.735 * size))
            
            path.move(to: CGPoint(x: 0.175 * size, y: 0.25 * size))
            path.addQuadCurve(to: CGPoint(x: 0.525 * size, y: 0.63 * size), control: CGPointMake(0.305 * size, 0.445 * size))
            
            path.move(to: CGPoint(x: 0.175 * size, y: 0.25 * size))
            path.addQuadCurve(to: CGPoint(x: 0.475 * size, y: 0.475 * size), control: CGPointMake(0.36 * size, 0.405 * size))
            
            path.move(to: CGPoint(x: 0.26 * size, y: 0.205 * size))
            path.addQuadCurve(to: CGPoint(x: 0.475 * size, y: 0.475 * size), control: CGPointMake(0.4 * size, 0.405 * size))
            
            path.move(to: CGPoint(x: 0.26 * size, y: 0.205 * size))
            path.addQuadCurve(to: CGPoint(x: 0.63 * size, y: 0.505 * size), control: CGPointMake(0.465 * size, 0.405 * size))
            
            path.move(to: CGPoint(x: 0.565 * size, y: 0.145 * size))
            path.addQuadCurve(to: CGPoint(x: 0.63 * size, y: 0.505 * size), control: CGPointMake(0.7 * size, 0.355 * size))
        }

        return path
    }
}

我在另一个视图中添加了鸟的图形并设置了动画,如下所示:

struct TestView: View {
    @State private var percentage: CGFloat = 0
    
    var body: some View {
        ZStack {
            Color(.black)
            SwiftBird()
                .trim(from: 0, to: percentage)
                .stroke(Color.white, style: StrokeStyle(lineWidth: 1, lineCap: .round, lineJoin: .round))
                .frame(width: 100, height: 100)
                .animation(.easeInOut(duration: 5.0), value: percentage)
                .onAppear {
                    self.percentage = 1.0
                }
        }
    }
}

一旦完成了路径的绘制,我想用 colored颜色 填充形状.然而,如果我对形状应用.fill(Color.orange)修改器,它不会正确填充内部的形状.我能够看到形状内部的黑色区域,而且 colored颜色 也超过了路径.我如何才能实现动画的色彩填充?如有任何帮助,我们不胜感激.

推荐答案

填充时,您的形状如下所示:

Swift logo, incorrectly filled

问题是您的形状不是单一的闭合子路径.它是一堆互不相连的子路径.每move(to:)个开始一个新的子路径.填充形状时,每个子路径都将闭合并单独填充.徽标的大部分内部没有被任何子路径包围,一些外部is被单独封闭的子路径包围.

下面是一个创建单个封闭子路径的版本:

struct SwiftBird: Shape {
    func path(in rect: CGRect) -> Path {
        let size = min(rect.width, rect.height)
        var path = Path()

        path.move(to: CGPoint(x: 0.565, y: 0.145))
        for (ex, ey, cx, cy): (CGFloat, CGFloat, CGFloat, CGFloat) in [
            (0.79, 0.62, 0.85, 0.34), // Upper wing outside
            (0.845, 0.825, 0.88, 0.75), // Head top
            (0.67, 0.775, 0.78, 0.715), // Head bottom
            (0.5, 0.82, 0.6, 0.82), // Lower shoulder
            (0.1, 0.58, 0.25, 0.8), // Lower wing outside
            (0.525, 0.63, 0.325, 0.735), // Lower wing inside
            (0.175, 0.25, 0.305, 0.445), // Lower tail outside
            (0.475, 0.475, 0.36, 0.405), // Lower tail inside
            (0.26, 0.205, 0.4, 0.405), // Upper tail inside
            (0.63, 0.505, 0.465, 0.405), // Upper tail outside
            (0.565, 0.145, 0.7, 0.355), // Upper wing inside
        ] {
            path.addQuadCurve(
                to: CGPoint(x: ex, y: ey),
                control: CGPoint(x: cx, y: cy)
            )
        }

        path.closeSubpath()
        path = path.applying(.init(scaleX: size, y: size))
        return path
    }
}

抚摸它时,它看起来和你的一样:

Swift logo, stroked

但正确填充:

Swift logo, filled

让SwiftUI准确地在动画结尾填充徽标的一种方法是将其包装在自定义的Animatable View中:

struct AnimatedSwiftLogo: View, Animatable {
    var animatableData: Double

    var body: some View {
        ZStack {
            SwiftBird()
                .fill(animatableData == 1 ? .orange : .clear)
            SwiftBird()
                .trim(from: 0, to: animatableData)
                .stroke(Color.white, style: StrokeStyle(lineWidth: 1, lineCap: .round, lineJoin: .round))
        }
    }
}

struct TestView: View {
    @State private var percentage: CGFloat = 0
    
    var body: some View {
        ZStack {
            Color(.black)
            AnimatedSwiftLogo(animatableData: percentage)
                .frame(width: 100, height: 100)
                .animation(.easeInOut(duration: 5.0), value: percentage)
                .onAppear {
                    self.percentage = 1.0
                }
        }
    }
}

结果:

animation of the Swift logo being stroked over five seconds, then filled with orange instantly when the stroke is complete

Swift相关问答推荐

RealityKit如何获得两个相对大小相同的ModelEntity?

为什么变量不存储在 Swift 的过程数据区中

在 RealmSwift 中表示范围值?

有没有一种方法可以访问封闭实例ObservableObject以从属性包装器中的任何位置调用objectWillChange.send()

如何在 macOS/AppKit 的窗口选项卡上接受拖动项目的放置?

ConfirmationDialog取消swiftui中的错误

String(validatingUTF8:) 和 String(utf8String:) 之间有区别吗?

如何更新 UserDefault 中的特定值

自定义选取器的出现导致其他视图重新排列

在 Swift 中实现自定义异步序列

What is "SwiftPM.SPMRepositoryError error 5"?

在 ViewController 的 UICollectionView 中拉取刷新

不支持用作符合协议 AnyObject 的具体类型

为什么 swift 中的类没有存储类型属性?

为 UIActivityViewController Swift 设置不同的活动项

是 swift 中另一个日期的同一周、月、年的日期

无法推断泛型参数的参数

用 UIBezierPath 画一条线

swift 3 如何获取明天和昨天的日期(注意特殊情况)新月或新年

Xcode6 中的 Swift 类与 Cocoa Touch 类