import SwiftUI /// Wie sich Onyx bewegt. /// /// Drei Profile statt einzelner Regler. Wer Federkonstanten einzeln einstellen /// darf, stellt sie kaputt: Ausfahren und Einfahren müssen zueinander passen, /// und diese Beziehung ist es, die man wählt — nicht vier Zahlen. /// /// **Einfahren ist in jedem Profil kürzer als Ausfahren und schwingt nicht /// nach.** Beim Öffnen sieht man zu, beim Schließen ist man schon woanders; /// dieselbe Kurve rückwärts fühlt sich dort zäh an, und das Nachschwingen liest /// sich als Ruckler. public enum MotionProfile: String, CaseIterable, Sendable { /// Die Voreinstellung: schnell, mit einem Hauch Nachschwingen. Das gibt dem /// Panel Masse, statt es nur größer werden zu lassen. case snappy /// Deutlich mehr Nachschwingen. Verspielter, und bei häufigem Öffnen /// anstrengender. case bouncy /// Länger und ohne jedes Überschwingen. Für Bildschirme, auf denen viel /// gleichzeitig passiert. case calm /// Ausfahren. public var expand: Animation { switch self { case .snappy: .spring(response: 0.34, dampingFraction: 0.86) case .bouncy: .spring(response: 0.42, dampingFraction: 0.62) case .calm: .spring(response: 0.52, dampingFraction: 1.0) } } /// Einfahren. public var collapse: Animation { switch self { case .snappy: .spring(response: 0.24, dampingFraction: 1.0) case .bouncy: .spring(response: 0.28, dampingFraction: 0.85) case .calm: .spring(response: 0.36, dampingFraction: 1.0) } } /// Für Messwerte: sichtbar, aber ohne Pulsieren. public var value: Animation { switch self { case .snappy: .easeOut(duration: 0.25) case .bouncy: .easeOut(duration: 0.28) case .calm: .easeOut(duration: 0.40) } } /// Wie lange das Einfahren dauert. /// /// Der Fenstercontroller braucht die Zahl, nicht die Kurve: er blendet das /// Fenster erst danach aus. Wird sie zu klein angesetzt, reißt das Panel /// mitten in der Bewegung weg. public var collapseDuration: Double { switch self { case .snappy: 0.30 case .bouncy: 0.36 case .calm: 0.46 } } }