【发布时间】:2019-12-15 05:07:57
【问题描述】:
我真的很喜欢 SF Symbol 集合中的 Timer 符号,我想在 SwiftUI 中为它制作动画。有几种不同的方法可以做到这一点,最简单的一种是制作面部图像和手部图像,将它们拍在 ZStack 中,然后为 Image("hand") 视图设置动画。 我还可以将脸部和手部绘制为单独的形状,然后以相同的方式堆叠和制作动画,如下所示:
struct TimerFace: Shape {
func path(in rect: CGRect) -> Path {
var facePath = Path()
facePath.move(to: CGPoint(x: 50, y: 100))
facePath.addCurve(to: CGPoint(x: 100, y: 50), control1: CGPoint(x: 77.61, y: 100), control2: CGPoint(x: 100, y: 77.61))
facePath.addCurve(to: CGPoint(x: 50.05, y: 0), control1: CGPoint(x: 100, y: 22.44), control2: CGPoint(x: 77.66, y: 0))
facePath.addCurve(to: CGPoint(x: 44.74, y: 5.12), control1: CGPoint(x: 46.75, y: 0), control2: CGPoint(x: 44.74, y: 1.96))
facePath.addLine(to: CGPoint(x: 44.74, y: 22.01))
facePath.addCurve(to: CGPoint(x: 49.38, y: 26.79), control1: CGPoint(x: 44.74, y: 24.74), control2: CGPoint(x: 46.65, y: 26.79))
facePath.addCurve(to: CGPoint(x: 54.02, y: 22.01), control1: CGPoint(x: 52.11, y: 26.79), control2: CGPoint(x: 54.02, y: 24.74))
facePath.addLine(to: CGPoint(x: 54.02, y: 11.24))
facePath.addCurve(to: CGPoint(x: 88.76, y: 50), control1: CGPoint(x: 73.68, y: 13.3), control2: CGPoint(x: 88.76, y: 29.81))
facePath.addCurve(to: CGPoint(x: 50, y: 88.8), control1: CGPoint(x: 88.76, y: 71.44), control2: CGPoint(x: 71.58, y: 88.8))
facePath.addCurve(to: CGPoint(x: 11.24, y: 50), control1: CGPoint(x: 28.47, y: 88.8), control2: CGPoint(x: 11.2, y: 71.44))
facePath.addCurve(to: CGPoint(x: 19.62, y: 26.08), control1: CGPoint(x: 11.29, y: 41.05), control2: CGPoint(x: 14.4, y: 32.63))
facePath.addCurve(to: CGPoint(x: 19.67, y: 17.8), control1: CGPoint(x: 21.67, y: 23.06), control2: CGPoint(x: 22.11, y: 20.19))
facePath.addCurve(to: CGPoint(x: 11, y: 19.04), control1: CGPoint(x: 17.32, y: 15.5), control2: CGPoint(x: 13.44, y: 15.74))
facePath.addCurve(to: CGPoint(x: 0, y: 50), control1: CGPoint(x: 4.16, y: 27.56), control2: CGPoint(x: 0, y: 38.37))
facePath.addCurve(to: CGPoint(x: 50, y: 100), control1: CGPoint(x: 0, y: 77.61), control2: CGPoint(x: 22.39, y: 100))
return facePath
}
}
struct TimerHand: Shape {
func path(in rect: CGRect) -> Path {
var handPath = Path()
handPath.move(to: CGPoint(x: 7.93, y: 40))
handPath.addCurve(to: CGPoint(x: 15.8, y: 29.75), control1: CGPoint(x: 13.5, y: 39.9), control2: CGPoint(x: 16.88, y: 35.25))
handPath.addLine(to: CGPoint(x: 10.76, y: 2.77))
handPath.addCurve(to: CGPoint(x: 5.22, y: 2.77), control1: CGPoint(x: 10.03, y: -0.92), control2: CGPoint(x: 5.95, y: -0.92))
handPath.addLine(to: CGPoint(x: 0.21, y: 29.72))
handPath.addCurve(to: CGPoint(x: 7.93, y: 40), control1: CGPoint(x: -0.9, y: 35.25), control2: CGPoint(x: 2.44, y: 39.93))
return handPath
}
}
struct TimerView: View {
@State private var rotation = 0.0
var body: some View {
VStack {
ZStack {
TimerFace().frame(CGSize(width: 100,height: 100), alignment: .center)
TimerHand().frame(CGSize(width: 16,height: 64), alignment: .center)
.rotationEffect(.degrees(rotation), anchor: .center)
}
Slider(value: $rotation, in: 0...360, step: 1.0)
}
}
}
应该是这样的
我确实认为这有点像“作弊”。关于如何以“正确”方式执行此操作的任何建议,而不是动画手框架,动画路径本身?
【问题讨论】:
标签: swiftui