xcode 为什么我的代码在设置饱和度更改动画时会产生意外结果

6rqinv9w  于 2022-11-18  发布在  其他
关注(0)|答案(1)|浏览(127)

我一直在学习路径、形状和更多的东西,并尝试通过制作一个有很多动画可能性的矩形来练习。我得到的结果是非常出乎意料的(对我来说)。我使用的渐变在每个动画中都很奇怪
我试过查看是否有任何值意外更改,但没有效果。以下代码有此问题:

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()
    }
}
nimxete2

nimxete21#

struct ColorCyclingCircle中,amount的值是错误的:
变更:

amount = newValue.first.first

至:

amount = newValue.first.second

此外,在以下代码中:

.onTapGesture {
    withAnimation() {
        saturation = saturation == 1 ? 0 : 1
        colorCycle = colorCycle == 1 ? 0 : 1
        saturation = saturation == 1 ? 0 : 1
    }
}

您正在更改saturation两次。在设置这些值之前,动画不会发生,因此,如果saturation开始时不是1,则最终结果是saturation变为0。这肯定不是您想要的。

相关问题