Here is a more complete example of what I'm trying for:
import SwiftUI
struct Mark {
var offset: CGSize
var angle: Angle
init(offset: CGSize, angle: Angle) {
self.offset = offset
self.angle = angle
}
init(x: CGFloat, y: CGFloat, angle: Angle) {
self.offset = CGSize(width: x, height: y)
self.angle = angle
}
}
struct ContentView: View {
static let blackMarks: [Mark] = [
Mark(x: 0, y: 0, angle: .degrees(0)),
Mark(x: 50, y: 0, angle: .degrees(-90)),
Mark(x: 50, y: -100, angle: .degrees(-180)),
Mark(x: 0, y: -100, angle: .degrees(-270)),
Mark(x: 0, y: 0, angle: .degrees(-360))
]
static let redMarks: [Mark] = [
Mark(x: 0, y: 0, angle: .degrees(0)),
Mark(x: -50, y: 0, angle: .degrees(90)),
Mark(x: -50, y: 100, angle: .degrees(180)),
Mark(x: 0, y: 100, angle: .degrees(270)),
Mark(x: 0, y: 0, angle: .degrees(360))
]
var body: some View {
ZStack {
Rectangle().fill(.black).frame(width: 20, height: 30)
.keyframeAnimator(initialValue: Self.blackMarks[0]) { content, value in
content
.rotationEffect(value.angle)
.offset(value.offset)
} keyframes: { _ in
KeyframeTrack(\.offset) {
LinearKeyframe(Self.blackMarks[1].offset, duration: 1.0)
LinearKeyframe(Self.blackMarks[2].offset, duration: 1.0)
LinearKeyframe(Self.blackMarks[3].offset, duration: 1.0)
LinearKeyframe(Self.blackMarks[4].offset, duration: 1.0)
}
KeyframeTrack(\.angle) {
LinearKeyframe(Self.blackMarks[1].angle, duration: 1.0)
LinearKeyframe(Self.blackMarks[2].angle, duration: 1.0)
LinearKeyframe(Self.blackMarks[3].angle, duration: 1.0)
LinearKeyframe(Self.blackMarks[4].angle, duration: 1.0)
}
}
Rectangle().fill(.red).frame(width: 20, height: 30)
.keyframeAnimator(initialValue: Self.blackMarks[0]) { content, value in
content
.rotationEffect(value.angle)
.offset(value.offset)
} keyframes: { _ in
/* Now, generate the equivalent tracks and keyframes as a function of redMarks */
}
}
}
}
#Preview {
ContentView()
}