Pausenzeichen wieder ausgestanzt

„Weiß mit dünnem Rand" war für den Blitz bestellt, nicht für das
Pausenzeichen — ich hatte es auf beide angewendet. Bei fast vollem Akku
liegt das Zeichen auf weißer Füllung: das Weiß verschwindet darin, übrig
bleiben die dunklen Ränder als zwei Striche.

Das Pausenzeichen ist damit wieder ein Loch in der Füllung. Der Blitz
bleibt weiß mit Rand und fadend.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-08-13 13:07:32 +02:00
parent 8545cc421c
commit e79191d033

View File

@@ -174,12 +174,24 @@ public enum BatteryGlyph {
let glyphRect = CGRect(x: body.midX - glyphWidth / 2,
y: rect.midY - glyphHeight / 2,
width: glyphWidth, height: glyphHeight)
// Weiß mit dünnem schwarzem Rand und beim Laden fadend.
guard isCharging else {
// Das Pausenzeichen wird **ausgestanzt**: ein Loch in der Füllung.
//
// Weiß mit Rand funktioniert hier nicht bei fast vollem Akku
// liegt es auf weißer Füllung, das Weiß verschwindet darin und
// übrig bleiben die dunklen Ränder als zwei Striche.
NSGraphicsContext.saveGraphicsState()
glyph.draw(in: glyphRect, from: .zero, operation: .destinationOut, fraction: 1)
NSGraphicsContext.restoreGraphicsState()
return
}
// Der Blitz: weiß mit dünnem dunklem Rand, und fadend.
//
// Der Rand ist immer die Gegenfarbe zur Füllung. Damit bleibt das
// Zeichen in **jedem** Moment des Fadens lesbar: über der hellen
// Füllung trägt es der Rand, über dem leeren Teil die Füllung selbst.
let whiteness = isCharging ? boltWhiteness(phase: fadePhase) : 1
// Der Rand ist immer die Gegenfarbe zur Füllung. Damit bleibt er in
// **jedem** Moment des Fadens lesbar: über der hellen Füllung trägt ihn
// der Rand, über dem leeren Teil die Füllung selbst.
let whiteness = boltWhiteness(phase: fadePhase)
if let outline = tint(glyph, with: NSColor(white: 1 - whiteness, alpha: 1)) {
outline.draw(in: outlineRect(glyphRect), from: .zero,
operation: .sourceOver, fraction: 1)
@@ -239,21 +251,25 @@ public struct BatteryGlyphView: View {
if let name = indicator.symbolName {
// `TimelineView` gibt die Zeit her, ohne dass hier ein
// Zeitgeber laufen muss.
TimelineView(.animation) { context in
let phase = isCharging
? context.date.timeIntervalSinceReferenceDate / BatteryGlyph.fadeDuration
: 0
let whiteness = isCharging
? BatteryGlyph.boltWhiteness(phase: phase) : 1
let size = BatteryGlyph.glyphHeight(for: indicator, in: height)
ZStack {
Image(systemName: name)
.font(.system(size: size + 2 * BatteryGlyph.outlineWidth))
.foregroundStyle(Color(white: 1 - whiteness))
Image(systemName: name)
.font(.system(size: size))
.foregroundStyle(Color(white: whiteness))
let size = BatteryGlyph.glyphHeight(for: indicator, in: height)
if isCharging {
TimelineView(.animation) { context in
let phase = context.date.timeIntervalSinceReferenceDate
/ BatteryGlyph.fadeDuration
let whiteness = BatteryGlyph.boltWhiteness(phase: phase)
ZStack {
Image(systemName: name)
.font(.system(size: size + 2 * BatteryGlyph.outlineWidth))
.foregroundStyle(Color(white: 1 - whiteness))
Image(systemName: name)
.font(.system(size: size))
.foregroundStyle(Color(white: whiteness))
}
}
} else {
Image(systemName: name)
.font(.system(size: size))
.blendMode(.destinationOut)
}
}
}