I have created the following custom wave shape
struct Wave: Shape {
private let frequency: Double
private let strength: Double
private var percentage: Double
init(frequency: Double, strength: Double, percentage: Double) {
self.frequency = frequency
self.strength = strength
self.percentage = percentage
}
func path(in rect: CGRect) -> Path {
let width = Double(rect.width)
let height = Double(rect.height)
let waveLength = width / frequency
var path = Path()
path.move(to: CGPoint(x: 0, y: height)
for x in stride(from: 0, to: width, by: 1) {
let sine = sin(x / waveLength)
let y = sine * strength
path.addLine(to: CGPoint(x: x, y: y)
}
return path
}
}
I now want my shape to grow and decrease vertically with an animation like it was a liquid filling a container. So I added a property called percentage
which I want to animate:
var animatableData: Double {
get { percentage }
set { percentage = newValue }
}
Down in the for
-loop I tweak the y
-coordinate of the wave:
let y = sine * strength + height * (1 - percentage)
The problem with this is that I cannot make the wave grow/decrease from the previous point, even though I use a state variable to hold the current percentage, which I update inside a withAnimation
block of the view as soon as the shape appears:
struct WaveView: View {
@State private var percentage: Double = 0
var body: some View {
Wave(frequency: 5, strength: 10, percentage: percentage)
.stroke()
.onAppear {
withAnimation(.linear) {
percentage = 0.5
}
}
}
}
The wave increases up to the midY of its frame, but if I then set it to 0.6, for example, the animation starts again from the beginning.
I kindly ask some help to fix this issue.
question from:
https://stackoverflow.com/questions/65647172/make-a-custom-shape-grow-and-decrease-with-an-animation 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…