Files
deepdrft/DeepDrftPublic.Client/Controls/MixVisualizerControls.razor
T

97 lines
3.7 KiB
Plaintext

@namespace DeepDrftPublic.Client.Controls
@using DeepDrftPublic.Client.Services
@inject MixVisualizerControlState ControlState
@* The Mix visualizer controls row (Phase 10, Wave 2). Four continuous sliders — resolution,
bubblyness, detach, color-shift speed — placed above the mix details and below the back button.
This component owns NO JS interop: it mutates the shared, session-scoped MixVisualizerControlState
and raises its Changed event. The backdrop bridge (MixWaveformVisualizer) subscribes to that event
and pushes the affected uniform to the WebGL module. That keeps the JS module handle single-owned
by the bridge and this component purely presentational. None of these is a seek surface (spec §D). *@
<div class="mix-visualizer-controls">
<div class="mix-visualizer-control">
<MudIcon Icon="@Icons.Material.Filled.ZoomIn" Size="Size.Small" Class="mix-visualizer-control-icon" />
<MudSlider T="double"
Value="@ResolutionFraction"
ValueChanged="@OnResolutionChanged"
Min="0"
Max="1"
Step="0.001"
Size="Size.Small"
Color="Color.Primary"
aria-label="Resolution (visible time-span)" />
</div>
<div class="mix-visualizer-control">
<MudIcon Icon="@Icons.Material.Filled.BubbleChart" Size="Size.Small" Class="mix-visualizer-control-icon" />
<MudSlider T="double"
Value="@ControlState.Bubblyness"
ValueChanged="@OnBubblynessChanged"
Min="0"
Max="1"
Step="0.001"
Size="Size.Small"
Color="Color.Primary"
aria-label="Bubblyness" />
</div>
<div class="mix-visualizer-control">
<MudIcon Icon="@Icons.Material.Filled.Air" Size="Size.Small" Class="mix-visualizer-control-icon" />
<MudSlider T="double"
Value="@ControlState.Detach"
ValueChanged="@OnDetachChanged"
Min="0"
Max="1"
Step="0.001"
Size="Size.Small"
Color="Color.Primary"
aria-label="Detach (unleash the lava lamp)" />
</div>
<div class="mix-visualizer-control">
<MudIcon Icon="@Icons.Material.Filled.Palette" Size="Size.Small" Class="mix-visualizer-control-icon" />
<MudSlider T="double"
Value="@ControlState.ColorShiftSpeed"
ValueChanged="@OnColorShiftSpeedChanged"
Min="0"
Max="1"
Step="0.001"
Size="Size.Small"
Color="Color.Primary"
aria-label="Color-shift speed" />
</div>
</div>
@code {
// Resolution rides the log mapping (slider fraction [0,1] ↔ visible seconds); the other three are
// already normalized [0,1] and bind to their state properties directly.
private double ResolutionFraction => MixZoomMapping.SecondsToFraction(ControlState.VisibleSeconds);
private void OnResolutionChanged(double fraction)
{
ControlState.VisibleSeconds = MixZoomMapping.FractionToSeconds(fraction);
ControlState.NotifyChanged();
}
private void OnBubblynessChanged(double value)
{
ControlState.Bubblyness = value;
ControlState.NotifyChanged();
}
private void OnDetachChanged(double value)
{
ControlState.Detach = value;
ControlState.NotifyChanged();
}
private void OnColorShiftSpeedChanged(double value)
{
ControlState.ColorShiftSpeed = value;
ControlState.NotifyChanged();
}
}