Files
ScarriffleandClaude Opus 5 ecb39fbe5f Eine Designschicht statt hundertfach gesetzter Zahlen
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>
2026-09-05 21:04:51 +02:00

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
}
}
}