I am trying to animate my path with a move value, It works almost, but the needed update to path happens after animation is done! Which must happen before Animation! How can I make it possible?
PS: The issue is about Path, and I am trying solve it through path.
struct HatchedShap: Shape {
let dis: CGFloat
var move: CGFloat
var animatableData: CGFloat {
get { return move }
set { move = newValue }
}
func path(in rect: CGRect) -> Path {
return Path { path in
for index in -Int(move*2.0)...Int((rect.height)/dis) {
path.move(to: CGPoint(x: rect.minX, y: rect.minY (CGFloat(index) move)*dis))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY (CGFloat(index) move)*dis))
}
}
}
}
use case:
struct ContentView: View {
@State private var move: CGFloat = CGFloat()
var body: some View {
HatchedShap(dis: 20.0, move: move)
.stroke(Color.red, style: StrokeStyle(lineWidth: 2.0))
.background(Color.black)
.frame(width: 100, height: 200)
.onTapGesture {
if (move == -0.5) { move = 0}
else { move = -0.5 }
}
.animation(Animation.linear(duration: 1.0), value: move)
}
}
CodePudding user response:
Small note:
You can simplify:
if (move == -0.5) {
move = 0
} else {
move = -0.5
}
To the following, which removes duplication & possibly faster because there is no branching (depends on if the compiler optimizes this):
move = -0.5 - move
CodePudding user response:
In your path
code, assign y
to a let
constant and check to make sure it is larger than 0
before adding the line to the path:
struct HatchedShap: Shape {
let dis: CGFloat
var move: CGFloat
var animatableData: CGFloat {
get { return move }
set { move = newValue }
}
func path(in rect: CGRect) -> Path {
return Path { path in
for index in -Int(move*2.0)...Int((rect.height)/dis) {
let y = rect.minY (CGFloat(index) move)*dis
if y > 0 {
path.move(to: CGPoint(x: rect.minX, y: y))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY (CGFloat(index) move)*dis))
}
}
}
}
}