Token für Schrift, Symbolgröße, Abstand, Radius und Bewegung, dazu sieben Bauteile, die vorher in jeder Kachel neu gebaut wurden — Karte, Abschnittstitel, Hinweis, Pillenknopf, Regler, Ablegefläche, Haarlinie. Symbole bekommen eine **eigene** Staffel und nicht die der Schrift: ein 9-Punkt-Symbol neben 9-Punkt-Text wirkt kleiner, nicht gleich groß. Beide in eine Staffel zu zwingen hieße, an jeder Stelle gegen sie zu arbeiten. Das Flächenrezept — Tint, Bänderung, Kante — stand zweimal da, einmal für das Panel und einmal für Fenster. Es ist jetzt `OnyxStone`, generisch über die Form, damit auch die animierende Notch-Silhouette es benutzen kann. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
67 lines
2.2 KiB
Swift
67 lines
2.2 KiB
Swift
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
|
|
}
|
|
}
|
|
}
|