broken changes
This commit is contained in:
@@ -918,6 +918,8 @@ private struct DJPlatter: View {
|
||||
var markerEnabled = true
|
||||
@State private var lastAngle: Double?
|
||||
var body: some View {
|
||||
TimelineView(.animation(minimumInterval:1.0/60,paused:!player.playing)) { _ in
|
||||
let displayTime = player.displayTime
|
||||
GeometryReader { geometry in
|
||||
ZStack {
|
||||
Circle().fill(Color.black.opacity(0.55)).overlay { Circle().stroke(color.opacity(0.4),lineWidth:3) }
|
||||
@@ -929,7 +931,7 @@ private struct DJPlatter: View {
|
||||
Rectangle().fill(color).frame(width:5,height:26).offset(y:-geometry.size.height*0.37)
|
||||
Circle().fill(.white).frame(width:5,height:5).offset(y:-geometry.size.height*0.45)
|
||||
}
|
||||
}.rotationEffect(.degrees(player.time*200))
|
||||
}.rotationEffect(.degrees(displayTime*200))
|
||||
}.contentShape(Circle())
|
||||
.gesture(DragGesture(minimumDistance:2).onChanged { drag in
|
||||
let angle = atan2(Double(drag.location.y-geometry.size.height/2),Double(drag.location.x-geometry.size.width/2))
|
||||
@@ -937,6 +939,7 @@ private struct DJPlatter: View {
|
||||
lastAngle = angle
|
||||
}.onEnded{_ in lastAngle = nil})
|
||||
}.accessibilityLabel("Deck \(letter) jog platter").accessibilityValue(player.playing ? "Rotating" : "Paused").help("Drag around the platter to jog (2 seconds per turn). Rotation follows source playback time.")
|
||||
}
|
||||
}
|
||||
}
|
||||
private struct DJWaveform: View {
|
||||
@@ -945,6 +948,8 @@ private struct DJWaveform: View {
|
||||
let color: Color
|
||||
var bpm: Double?
|
||||
var body: some View {
|
||||
TimelineView(.animation(minimumInterval:1.0/60,paused:!player.playing)) { _ in
|
||||
let displayTime = player.displayTime
|
||||
GeometryReader { geometry in
|
||||
Canvas { context,size in
|
||||
let values = player.waveform
|
||||
@@ -952,16 +957,17 @@ private struct DJWaveform: View {
|
||||
let count = max(1,Int(size.width/2))
|
||||
for i in 0..<count {
|
||||
let index = min(values.count-1,i*values.count/count),height = max(1,Double(values[index])*size.height)
|
||||
context.fill(Path(CGRect(x:Double(i)*size.width/Double(count),y:(size.height-height)/2,width:1.4,height:height)),with:.color(color.opacity(Double(i)/Double(count) < player.time/max(0.001,player.duration) ? 0.4 : 0.9)))
|
||||
context.fill(Path(CGRect(x:Double(i)*size.width/Double(count),y:(size.height-height)/2,width:1.4,height:height)),with:.color(color.opacity(Double(i)/Double(count) < displayTime/max(0.001,player.duration) ? 0.4 : 0.9)))
|
||||
}
|
||||
DJWaveMarkers.draw(context:&context,size:size,start:0,span:player.duration,bpm:bpm,loop:player.loopEnabled ? player.loopIn.flatMap { a in player.loopOut.map { a...$0 } } : nil)
|
||||
|
||||
let x = player.time/max(0.001,player.duration)*size.width
|
||||
let x = displayTime/max(0.001,player.duration)*size.width
|
||||
context.fill(Path(CGRect(x:x,y:0,width:1.5,height:size.height)),with:.color(.white))
|
||||
}.background(.black.opacity(0.3),in:RoundedRectangle(cornerRadius:3))
|
||||
.overlay { if player.waveformLoading { ProgressView().controlSize(.mini) } else if player.waveformUnavailable { Text("Waveform unavailable").font(.caption2).foregroundStyle(.secondary) } }
|
||||
.modifier(DJLoopWaveInteraction(player:player,start:0,span:player.duration,width:geometry.size.width,frozenStart:$frozenStart))
|
||||
}.accessibilityLabel("Track waveform and position").accessibilityValue(DJStyle.stamp(player.time)).accessibilityAdjustableAction { player.jog($0 == .increment ? 1 : -1) }
|
||||
}
|
||||
}
|
||||
}
|
||||
private struct DJMappingSheet: View {
|
||||
@@ -1224,10 +1230,12 @@ private struct DJCentreWaveform: View {
|
||||
var settings = DJPreferences()
|
||||
@State private var frozenStart: Double?
|
||||
var body: some View {
|
||||
TimelineView(.animation(minimumInterval:1.0/60,paused:!player.playing)) { _ in
|
||||
let displayTime = player.displayTime
|
||||
GeometryReader { geometry in
|
||||
Canvas { context,size in
|
||||
guard !player.waveform.isEmpty,player.duration > 0 else { return }
|
||||
let span = settings.waveformSeconds,start = frozenStart ?? (player.time-span/2),count = max(1,Int(size.width/2))
|
||||
let span = settings.waveformSeconds,start = frozenStart ?? (displayTime-span/2),count = max(1,Int(size.width/2))
|
||||
for second in 0...8 {
|
||||
let x = Double(second)/8*size.width
|
||||
context.fill(Path(CGRect(x:x,y:0,width:0.5,height:size.height)),with:.color(.white.opacity(settings.showTimeGrid ? 0.15 : 0)))
|
||||
@@ -1235,8 +1243,10 @@ private struct DJCentreWaveform: View {
|
||||
for i in 0..<count {
|
||||
let seconds = start+Double(i)/Double(count)*span
|
||||
guard seconds >= 0,seconds < player.duration else { continue }
|
||||
let index = min(player.waveform.count-1,Int(seconds/player.duration*Double(player.waveform.count)))
|
||||
let height = max(1,Double(player.waveform[index])*size.height*0.85)
|
||||
let sample = min(Double(player.waveform.count-1),seconds/player.duration*Double(player.waveform.count))
|
||||
let index = Int(sample),next = min(player.waveform.count-1,index+1),fraction = sample-Double(index)
|
||||
let amplitude = Double(player.waveform[index])*(1-fraction)+Double(player.waveform[next])*fraction
|
||||
let height = max(1,amplitude*size.height*0.85)
|
||||
var shade = color
|
||||
if settings.spectralWaveforms,player.waveformBands.indices.contains(index) {
|
||||
let band = player.waveformBands[index],sum = max(0.0001,band.low+band.mid+band.high)
|
||||
@@ -1245,10 +1255,12 @@ private struct DJCentreWaveform: View {
|
||||
context.fill(Path(CGRect(x:Double(i)*size.width/Double(count),y:(size.height-height)/2,width:1.5,height:height)),with:.color(shade))
|
||||
}
|
||||
DJWaveMarkers.draw(context:&context,size:size,start:start,span:span,bpm:bpm,loop:player.loopEnabled ? player.loopIn.flatMap { a in player.loopOut.map { a...$0 } } : nil)
|
||||
context.fill(Path(CGRect(x:size.width/2,y:0,width:1.5,height:size.height)),with:.color(.red))
|
||||
let playhead = (displayTime-start)/span*size.width
|
||||
context.fill(Path(CGRect(x:playhead,y:0,width:1.5,height:size.height)),with:.color(.red))
|
||||
}.overlay(alignment:.topLeading) { Text(letter+" · \(Int(settings.waveformSeconds)) s").font(.system(size:9,weight:.semibold)).foregroundStyle(color).padding(5) }
|
||||
.modifier(DJLoopWaveInteraction(player:player,start:player.time-settings.waveformSeconds/2,span:settings.waveformSeconds,width:geometry.size.width,frozenStart:$frozenStart))
|
||||
.modifier(DJLoopWaveInteraction(player:player,start:displayTime-settings.waveformSeconds/2,span:settings.waveformSeconds,width:geometry.size.width,frozenStart:$frozenStart))
|
||||
}.accessibilityLabel("Deck \(letter) scrolling waveform").accessibilityValue(DJStyle.stamp(player.time))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1607,7 +1619,10 @@ enum DJWaveMarkers {
|
||||
if let bpm {
|
||||
for beat in beats(start:start,span:span,bpm:bpm,width:size.width) {
|
||||
let x = (Double(beat)*60/bpm-start)/span*size.width
|
||||
context.fill(Path(CGRect(x:x,y:0,width:beat % 4 == 0 ? 1.2 : 0.6,height:size.height)),with:.color(.white.opacity(beat % 4 == 0 ? 0.5 : 0.22)))
|
||||
context.fill(Path(CGRect(x:x,y:0,width:beat % 4 == 0 ? 1.2 : 0.6,height:size.height)),with:.color(beat % 4 == 0 ? .yellow.opacity(0.85) : .white.opacity(0.4)))
|
||||
if beat % 4 == 0,size.height >= 45 {
|
||||
context.draw(Text("\(beat/4+1)").font(.system(size:9,weight:.semibold)).foregroundColor(.yellow),at:CGPoint(x:x+5,y:9),anchor:.leading)
|
||||
}
|
||||
}
|
||||
}
|
||||
if let loop {
|
||||
|
||||
Reference in New Issue
Block a user