import Foundationenum LoadingPattern: CaseIterable { case knightRider case cylon case outsideIn case race case pulse // Secondary offset so the lower bar moves differently. var secondaryOffset: Double { switch self { case .knightRider: .pi case .cylon: .pi / 2 case .outsideIn: .pi case .race: .pi / 3 case .pulse: .pi / 2 } } func value(phase: Double) -> Double { let v: Double switch self { case .knightRider: v = 0.5 + 0.5 * sin(phase) // ping-pong case .cylon: let t = phase.truncatingRemainder(dividingBy: .pi * 2) / (.pi * 2) v = t // sawtooth 0→1 case .outsideIn: v = abs(cos(phase)) // high at edges, dip center case .race: let t = (phase * 1.2).truncatingRemainder(dividingBy: .pi * 2) / (.pi * 2) v = t case .pulse: v = 0.4 + 0.6 * (0.5 + 0.5 * sin(phase)) // 40–100% } return max(0, min(v * 100, 100)) }}extension Notification.Name { static let codexbarDebugReplayAllAnimations = Notification.Name("codexbarDebugReplayAllAnimations")}
import Foundation
enum LoadingPattern: CaseIterable {
case knightRider
case cylon
case outsideIn
case race
case pulse
// Secondary offset so the lower bar moves differently.
var secondaryOffset: Double {
switch self {
case .knightRider: .pi
case .cylon: .pi / 2
case .outsideIn: .pi
case .race: .pi / 3
case .pulse: .pi / 2
}
}
func value(phase: Double) -> Double {
let v: Double
switch self {
case .knightRider:
v = 0.5 + 0.5 * sin(phase) // ping-pong
case .cylon:
let t = phase.truncatingRemainder(dividingBy: .pi * 2) / (.pi * 2)
v = t // sawtooth 0→1
case .outsideIn:
v = abs(cos(phase)) // high at edges, dip center
case .race:
let t = (phase * 1.2).truncatingRemainder(dividingBy: .pi * 2) / (.pi * 2)
v = t
case .pulse:
v = 0.4 + 0.6 * (0.5 + 0.5 * sin(phase)) // 40–100%
}
return max(0, min(v * 100, 100))
}
}
extension Notification.Name {
static let codexbarDebugReplayAllAnimations = Notification.Name("codexbarDebugReplayAllAnimations")
}