lol more fixes

This commit is contained in:
Dallas Groot 2026-04-05 08:43:08 -07:00
parent 2b879fd153
commit 0df9057add

View file

@ -176,25 +176,22 @@ struct MitsuhaVisualizerView: View {
var body: some View {
Group {
if settings.enabled {
// .animation fires as part of SwiftUI's animation pass always redraws Canvas.
// The Canvas closure must capture a CHANGING VALUE TYPE (timeline.date) so
// SwiftUI knows to re-invoke the draw closure each tick. Without this, Canvas
// sees only `box` (a class reference SwiftUI can't track class mutations)
// and skips the redraw, producing a static frozen wave.
TimelineView(.animation(minimumInterval: 1.0 / settings.effectiveFPS)) { timeline in
let rawLevels: [Float] = isPlaying
? (previewLevels ?? AudioPlayer.shared.currentLevels())
: Array(repeating: Float(0), count: max(settings.numberOfPoints, 1))
let _ = updateDisplayLevels(newRawLevels: rawLevels)
let _ = updateWobblePhase(date: timeline.date)
// Capture the changing Date so SwiftUI detects a change and
// calls the Canvas drawing closure on every timeline tick.
let frameDate = timeline.date
// .periodic fires on a fixed wall-clock interval regardless of SwiftUI animation state.
// Update calls are moved INSIDE the Canvas closure = plain imperative code,
// not @ViewBuilder guaranteed to execute on every tick.
// `t` is a changing Date captured by Canvas: SwiftUI sees the closure environment
// changed each tick always re-executes the drawing closure.
TimelineView(.periodic(from: .now, by: 1.0 / settings.effectiveFPS)) { timeline in
let t = timeline.date // changes every tick forces Canvas redraw
Canvas { context, size in
// Plain imperative context these calls always execute, no ViewBuilder rules
let rawLevels: [Float] = isPlaying
? (previewLevels ?? AudioPlayer.shared.currentLevels())
: Array(repeating: Float(0), count: max(settings.numberOfPoints, 1))
updateDisplayLevels(newRawLevels: rawLevels)
updateWobblePhase(date: t)
Canvas(opaque: false) { context, size in
// Reference frameDate so the compiler keeps the capture.
// This tells SwiftUI the closure's environment changed redraw.
let _ = frameDate
let pts = box.displayLevels.isEmpty
? Array(repeating: Float(settings.idleAmplitude), count: settings.numberOfPoints)
: box.displayLevels
@ -206,11 +203,6 @@ struct MitsuhaVisualizerView: View {
}
}
}
// Only animate opacity changes when a song is loaded.
// During a song transition, isPlaying briefly flips falsetrue which
// would fade the wave to 0.35, snap it to idle, then fade back up
// producing the visible "lift". Holding opacity steady during the gap
// prevents this.
.opacity(isPlaying ? 1.0 : (isSongLoaded ? 0.35 : 1.0))
.animation(isSongLoaded ? .easeInOut(duration: 0.6) : nil, value: isPlaying)
.onAppear {