Reputation: 1748
Is it possible to animate a Path without creating a SubView?
Eg.
struct ContentView: View {
@State private var end = 0.0
var body: some View {
VStack {
Button("Press me") {
withAnimation {
end += 100
}
}
Path { path in
path.move(to: .zero)
path.addLine(to: CGPoint(x: end, y: end))
}
.stroke()
}
}
}
I know we can extract the Path
into a SubView and use the animatableData
property to animate it, however, I was wondering if this is achievable without doing that (animating the Path
directly).
What I've tried:
I thought making ContentView
animatable and using the required animatableData
property within ContentView
itself would help.
Eg.
struct ContentView: View {
@State private var end = 0.0
var animatableData: Double {
get { end }
set { end = newValue }
}
var body: some View {
VStack {
Button("Press me") {
withAnimation {
end += 100
}
}
Path { path in
path.move(to: .zero)
path.addLine(to: CGPoint(x: end, y: end))
}
.stroke()
}
}
}
This didn't work unfortunately. I also tried adding .animation
modifiers to Path
but that still didn't do the job.
Is it possible to animate this Path
without wrapping it in a Shape
or a different type of SubView? I wan't to be able to change end
and have the change be animated without wrapping the Path
in a different view.
Thanks in advance!
Upvotes: 0
Views: 158
Reputation: 17419
You can use .trim modifier with .animation modifier.
struct PathAnimationView: View {
@State private var end = 0.0
@State private var trimStart: CGFloat = 0
@State private var trimEnd: CGFloat = 0
var body: some View {
VStack {
Button("Press me") {
withAnimation {
trimStart = 0.0
end += 100
trimEnd = 1
}
}
Path { path in
path.move(to: .zero)
path.addLine(to: CGPoint(x: end, y: end))
}
.trim(from: trimStart, to: trimEnd)
.stroke()
.animation(.easeOut(duration: 1.0), value: 1)
}
}
}
Limitation: .trim will animate path from start to end once.
So better user Shape class to do this.
Upvotes: 1