feat(public): scrolling Canvas 2D Mix visualizer — windowed, playback-coupled, zoomable, read-only (8.K W2)
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
namespace DeepDrftPublic.Client.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Pure mapping between the Mix visualizer's zoom slider position [0, 1] and the visible time-span in
|
||||
/// seconds. The span range is wide (0.333 s … 30 s, ~90×), so the mapping is logarithmic — equal
|
||||
/// slider travel changes the span by an equal *ratio*, which feels even to the hand. Slider
|
||||
/// orientation: fraction 0 = most zoomed-out (longest span), fraction 1 = most zoomed-in (the
|
||||
/// 0.333 s quarter-note-@-180-BPM anchor). Extracted from the component so the math is unit-testable.
|
||||
/// </summary>
|
||||
public static class MixZoomMapping
|
||||
{
|
||||
/// <summary>Shortest span (max zoom): one quarter note at 180 BPM = 60/180 s. Hard anchor.</summary>
|
||||
public const double MinVisibleSeconds = 60.0 / 180.0;
|
||||
|
||||
/// <summary>Longest span (min zoom). Tunable.</summary>
|
||||
public const double MaxVisibleSeconds = 30.0;
|
||||
|
||||
/// <summary>Slider position [0, 1] -> visible seconds. 0 = zoomed out, 1 = zoomed in.</summary>
|
||||
public static double FractionToSeconds(double fraction)
|
||||
{
|
||||
fraction = Math.Clamp(fraction, 0, 1);
|
||||
var logMax = Math.Log(MaxVisibleSeconds);
|
||||
var logMin = Math.Log(MinVisibleSeconds);
|
||||
// Interpolate in log space from out (frac 0 -> logMax) to in (frac 1 -> logMin).
|
||||
return Math.Exp(logMax + (logMin - logMax) * fraction);
|
||||
}
|
||||
|
||||
/// <summary>Visible seconds -> slider position [0, 1]. Inverse of <see cref="FractionToSeconds"/>.</summary>
|
||||
public static double SecondsToFraction(double seconds)
|
||||
{
|
||||
seconds = Math.Clamp(seconds, MinVisibleSeconds, MaxVisibleSeconds);
|
||||
var logMax = Math.Log(MaxVisibleSeconds);
|
||||
var logMin = Math.Log(MinVisibleSeconds);
|
||||
return (logMax - Math.Log(seconds)) / (logMax - logMin);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user