I've been learning paths shapes and more and tried to practice by making a rectangle with lots of animation possibility. The results i achieved were very unexpected(to me). The gradients that i used just weird out at every animation
i've tried seeing if any values changed unexpectedly but to no avail. heres the code that has this problem:
import SwiftUI
struct ColorCyclingCircle: View, Animatable {
var amount = 0.0
var steps = 100.0
var saturation = 1.0
var brightness1 = 1.0
var brightness2 = 0.5
var animatableData: AnimatablePair<AnimatablePair<Double, Double>, Double> {
get { AnimatablePair(AnimatablePair(steps, amount), saturation) }
set {
steps = newValue.first.first
amount = newValue.first.first
saturation = newValue.second
}
}
var body: some View {
ZStack {
ForEach(0..<Int(steps), id: \.self) { value in
Rectangle()
.inset(by: Double(value))
.strokeBorder(
LinearGradient(
gradient: Gradient(colors: [
color(for: value, brightness: brightness1),
color(for: value, brightness: brightness2)
]),
startPoint: .top,
endPoint: .bottom
),
lineWidth: 2
)
}
}
.drawingGroup()
}
func color(for value: Int, brightness: Double) -> Color {
var targetHue = Double(value) / Double(steps) amount
if targetHue > 1 {
targetHue -= 1
}
return Color(hue: targetHue, saturation: saturation, brightness: brightness)
}
}
struct ContentView: View {
@State private var colorCycle = 0.0
@State private var steps = 100.0
@State private var saturation = 1.0
@State private var brightness1 = 1.0
@State private var brightness2 = 0.5
var body: some View {
VStack {
ColorCyclingCircle(amount: colorCycle, steps: steps, saturation: saturation, brightness1: brightness1, brightness2: brightness2)
.frame(width: 300, height: 300)
.onTapGesture {
withAnimation() {
saturation = saturation == 1 ? 0 : 1
colorCycle = colorCycle == 1 ? 0 : 1
saturation = saturation == 1 ? 0 : 1
}
}
Spacer()
.frame(height: 100)
Text("Color")
Slider(value: $colorCycle)
Text("Saturation")
Slider(value: $saturation)
Text("Brightness")
Slider(value: $brightness1)
Slider(value: $brightness2)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
CodePudding user response:
In struct ColorCyclingCircle
, you're getting the wrong value for amount
:
Change:
amount = newValue.first.first
to:
amount = newValue.first.second
Also, in this code:
.onTapGesture {
withAnimation() {
saturation = saturation == 1 ? 0 : 1
colorCycle = colorCycle == 1 ? 0 : 1
saturation = saturation == 1 ? 0 : 1
}
}
you are changing saturation
twice. The animation won't happen until after these values have been set, so the end result is that saturation
goes to 0
if it started as anything but 1
. That's surely not what you intended.