fix: album art corner radius load delay

This commit is contained in:
Zhe Fang
2025-11-30 11:00:05 -05:00
parent be9a67f57d
commit 794079f20b
17 changed files with 178 additions and 85 deletions

View File

@@ -5,6 +5,6 @@ namespace BetterLyrics.WinUI3.Constants
public static class Time
{
public static readonly TimeSpan DebounceTimeout = TimeSpan.FromMilliseconds(250);
public static readonly TimeSpan AnimationDuration = TimeSpan.FromMilliseconds(250);
public static readonly TimeSpan AnimationDuration = TimeSpan.FromMilliseconds(350);
}
}

View File

@@ -117,6 +117,21 @@
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageSpectrumLayerStyle" IsEnabled="{x:Bind LyricsBackgroundSettings.IsSpectrumOverlayEnabled, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind LyricsBackgroundSettings.SpectrumStyle, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageSpectrumStyleCurve" />
<ComboBoxItem x:Uid="SettingsPageSpectrumStyleBar" />
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsBackgroundSettings.IsSpectrumOverlayEnabled, Mode=OneWay}">
<uc:ExtendedSlider
Default="128"
Maximum="1024"
Minimum="1"
Value="{x:Bind LyricsBackgroundSettings.SpectrumCount, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>

View File

@@ -301,9 +301,10 @@ namespace BetterLyrics.WinUI3.Controls
resourceCreator: sender,
ds: args.DrawingSession,
spectrumData: _spectrumAnalyzer?.SmoothSpectrum,
barCount: _spectrumAnalyzer?.BarCount ?? 0,
barCount: _spectrumAnalyzer?.BarCount ?? 1,
isEnabled: lyricsBg.IsSpectrumOverlayEnabled,
placement: lyricsBg.SpectrumPlacement,
style: lyricsBg.SpectrumStyle,
canvasWidth: sender.Size.Width,
canvasHeight: sender.Size.Height,
fillColor: lyricsThemeColors.BgFontColor
@@ -422,7 +423,7 @@ namespace BetterLyrics.WinUI3.Controls
if (lyricsBg.IsSpectrumOverlayEnabled && !_spectrumAnalyzer.IsCapturing)
{
_spectrumAnalyzer.BarCount = 64;
_spectrumAnalyzer.BarCount = lyricsBg.SpectrumCount;
_spectrumAnalyzer.StartCapture();
}
else if (!lyricsBg.IsSpectrumOverlayEnabled && _spectrumAnalyzer.IsCapturing)

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BetterLyrics.WinUI3.Enums
{
public enum SpectrumStyle
{
Curve,
Bar
}
}

View File

@@ -29,7 +29,7 @@ namespace BetterLyrics.WinUI3.Helper
private float[]? _currentSpectrum;
public float[]? SmoothSpectrum { get; private set; }
public int BarCount { get; set; } = 16;
public int BarCount { get; set; } = 64;
public int Sensitivity { get; set; } = 100;
public float SmoothingFactor { get; set; } = 0.95f;
public bool IsCapturing { get; private set; } = false;

View File

@@ -18,6 +18,8 @@ namespace BetterLyrics.WinUI3.Models.Settings
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsSpectrumOverlayEnabled { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial SpectrumPlacement SpectrumPlacement { get; set; } = SpectrumPlacement.Bottom;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial SpectrumStyle SpectrumStyle { get; set; } = SpectrumStyle.Bar;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int SpectrumCount { get; set; } = 128;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsSnowFlakeOverlayEnabled { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int SnowFlakeOverlayAmount { get; set; } = 10;

View File

@@ -13,7 +13,7 @@ using Windows.UI;
namespace BetterLyrics.WinUI3.Renderer
{
public class FluidBackgroundRenderer : IDisposable
public partial class FluidBackgroundRenderer : IDisposable
{
private PixelShaderEffect? _fluidEffect;
private float _timeAccumulator = 0f;

View File

@@ -6,7 +6,7 @@ using System;
namespace BetterLyrics.WinUI3.Renderer
{
public class FogRenderer : IDisposable
public partial class FogRenderer : IDisposable
{
private PixelShaderEffect<FogEffect>? _fogEffect;
private float _timeAccumulator = 0f;

View File

@@ -6,7 +6,7 @@ using System;
namespace BetterLyrics.WinUI3.Renderer
{
public class SnowRenderer : IDisposable
public partial class SnowRenderer : IDisposable
{
private PixelShaderEffect<SnowEffect>? _snowEffect;
private float _timeAccumulator = 0f;

View File

@@ -11,7 +11,7 @@ using Windows.UI;
namespace BetterLyrics.WinUI3.Renderer
{
public class SpectrumRenderer : IDisposable
public partial class SpectrumRenderer : IDisposable
{
private CanvasGeometry? _spectrumGeometry;
@@ -22,6 +22,7 @@ namespace BetterLyrics.WinUI3.Renderer
int barCount,
bool isEnabled,
SpectrumPlacement placement,
SpectrumStyle style,
double canvasWidth,
double canvasHeight,
Color fillColor
@@ -32,7 +33,7 @@ namespace BetterLyrics.WinUI3.Renderer
if (!isEnabled || spectrumData == null || spectrumData.Length == 0) return;
_spectrumGeometry = CreateGeometry(resourceCreator, spectrumData, barCount, placement, canvasWidth, canvasHeight);
_spectrumGeometry = CreateGeometry(resourceCreator, spectrumData, barCount, placement, style, canvasWidth, canvasHeight);
if (_spectrumGeometry != null)
{
@@ -45,69 +46,115 @@ namespace BetterLyrics.WinUI3.Renderer
float[] data,
int barCount,
SpectrumPlacement placement,
SpectrumStyle style,
double width,
double height)
{
if (barCount < 2) return null;
var points = new Vector2[barCount];
float pointSpacing = (float)width / (barCount - 1);
float maxDataVal = 0;
for (int i = 0; i < barCount; i++)
int checkCount = Math.Min(barCount, data.Length);
for (int i = 0; i < checkCount; i++)
{
float val = i < data.Length ? data[i] : 0;
points[i] = new Vector2(i * pointSpacing, val);
if (data[i] > maxDataVal) maxDataVal = data[i];
}
// 限制高度
float maxY = 0;
foreach (var p in points) if (p.Y > maxY) maxY = p.Y;
float limitY = (float)height * 0.2f; // 高度限制为总高度的 20%
float scaleRatio = 1.0f;
float limitY = (float)height * 0.2f;
if (maxY > limitY)
if (maxDataVal > limitY)
{
float ratio = limitY / maxY;
for (int i = 0; i < points.Length; i++) points[i].Y *= ratio;
}
// 翻转 Y 轴
if (placement == SpectrumPlacement.Bottom)
{
for (int i = 0; i < points.Length; i++)
{
points[i].Y = (float)height - points[i].Y;
}
scaleRatio = limitY / maxDataVal;
}
using var pathBuilder = new CanvasPathBuilder(creator);
pathBuilder.BeginFigure(points[0]);
for (int i = 0; i < barCount - 1; i++)
if (style == SpectrumStyle.Bar)
{
Vector2 p0 = points[Math.Max(i - 1, 0)];
Vector2 p1 = points[i];
Vector2 p2 = points[i + 1];
Vector2 p3 = points[Math.Min(i + 2, barCount - 1)];
float totalStep = (float)width / barCount;
float gap = 2.0f;
float barWidth = totalStep - gap;
if (barWidth < 1.0f) { barWidth = totalStep; gap = 0f; }
Vector2 cp1 = p1 + (p2 - p0) / 6.0f;
Vector2 cp2 = p2 - (p3 - p1) / 6.0f;
for (int i = 0; i < barCount; i++)
{
float rawVal = i < data.Length ? data[i] : 0;
float barHeight = rawVal * scaleRatio;
if (barHeight < 0.5f) continue;
pathBuilder.AddCubicBezier(cp1, cp2, p2);
}
float x = i * totalStep;
float topY, bottomY;
// 封口
if (placement == SpectrumPlacement.Top)
{
pathBuilder.AddLine(new Vector2(points[barCount - 1].X, 0));
pathBuilder.AddLine(new Vector2(points[0].X, 0));
if (placement == SpectrumPlacement.Top)
{
topY = 0;
bottomY = barHeight;
}
else // Bottom
{
topY = (float)height - barHeight;
bottomY = (float)height;
}
// 绘制独立矩形
pathBuilder.BeginFigure(new Vector2(x, topY));
pathBuilder.AddLine(new Vector2(x + barWidth, topY));
pathBuilder.AddLine(new Vector2(x + barWidth, bottomY));
pathBuilder.AddLine(new Vector2(x, bottomY));
pathBuilder.EndFigure(CanvasFigureLoop.Closed);
}
}
else
{
pathBuilder.AddLine(new Vector2(points[barCount - 1].X, (float)height));
pathBuilder.AddLine(new Vector2(points[0].X, (float)height));
var points = new Vector2[barCount];
float pointSpacing = (float)width / (barCount - 1);
for (int i = 0; i < barCount; i++)
{
float rawVal = i < data.Length ? data[i] : 0;
float y = rawVal * scaleRatio;
// 处理翻转
if (placement == SpectrumPlacement.Bottom)
{
y = (float)height - y;
}
points[i] = new Vector2(i * pointSpacing, y);
}
// 绘制曲线
pathBuilder.BeginFigure(points[0]);
for (int i = 0; i < barCount - 1; i++)
{
Vector2 p0 = points[Math.Max(i - 1, 0)];
Vector2 p1 = points[i];
Vector2 p2 = points[i + 1];
Vector2 p3 = points[Math.Min(i + 2, barCount - 1)];
Vector2 cp1 = p1 + (p2 - p0) / 6.0f;
Vector2 cp2 = p2 - (p3 - p1) / 6.0f;
pathBuilder.AddCubicBezier(cp1, cp2, p2);
}
// 封口
if (placement == SpectrumPlacement.Top)
{
pathBuilder.AddLine(new Vector2(points[barCount - 1].X, 0));
pathBuilder.AddLine(new Vector2(points[0].X, 0));
}
else
{
pathBuilder.AddLine(new Vector2(points[barCount - 1].X, (float)height));
pathBuilder.AddLine(new Vector2(points[0].X, (float)height));
}
pathBuilder.EndFigure(CanvasFigureLoop.Closed);
}
pathBuilder.EndFigure(CanvasFigureLoop.Closed);
return CanvasGeometry.CreatePath(pathBuilder);
}

View File

@@ -1414,12 +1414,21 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageSpectrumLayerPlacement.Header" xml:space="preserve">
<value>Spectrum placement</value>
</data>
<data name="SettingsPageSpectrumLayerStyle.Header" xml:space="preserve">
<value>Spectrum style</value>
</data>
<data name="SettingsPageSpectrumPlacementBottom.Content" xml:space="preserve">
<value>Bottom</value>
</data>
<data name="SettingsPageSpectrumPlacementTop.Content" xml:space="preserve">
<value>Top</value>
</data>
<data name="SettingsPageSpectrumStyleBar.Content" xml:space="preserve">
<value>Bar</value>
</data>
<data name="SettingsPageSpectrumStyleCurve.Content" xml:space="preserve">
<value>Curve</value>
</data>
<data name="SettingsPageSpeed.Header" xml:space="preserve">
<value>Motion rate</value>
</data>

View File

@@ -952,6 +952,9 @@
<data name="SettingsPageLayoutOrientationVertical.Content" xml:space="preserve">
<value>垂直方向</value>
</data>
<data name="SettingsPageLeft.Content" xml:space="preserve">
<value>左</value>
</data>
<data name="SettingsPageLeftGapFactor.Header" xml:space="preserve">
<value>左ギャップエリア幅係数</value>
</data>
@@ -1066,6 +1069,9 @@
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>オリジナルのハイライト範囲</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>左</value>
</data>
<data name="SettingsPageLyricsLight.Content" xml:space="preserve">
<value>ライト</value>
</data>
@@ -1306,6 +1312,9 @@
<data name="SettingsPageRestart.Content" xml:space="preserve">
<value>変更を適用するためのアプリを再起動します</value>
</data>
<data name="SettingsPageRight.Content" xml:space="preserve">
<value>右</value>
</data>
<data name="SettingsPageRightGapFactor.Header" xml:space="preserve">
<value>右ギャップエリア幅係数</value>
</data>
@@ -1393,12 +1402,6 @@
<data name="SettingsPageSongInfo.Text" xml:space="preserve">
<value>曲情報</value>
</data>
<data name="SettingsPageLeft.Content" xml:space="preserve">
<value>左</value>
</data>
<data name="SettingsPageRight.Content" xml:space="preserve">
<value>右</value>
</data>
<data name="SettingsPageSongStatus.Header" xml:space="preserve">
<value>現在の曲です</value>
</data>
@@ -1555,7 +1558,4 @@
<data name="UserGuide.Content" xml:space="preserve">
<value>利用案内</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>左</value>
</data>
</root>

View File

@@ -952,6 +952,9 @@
<data name="SettingsPageLayoutOrientationVertical.Content" xml:space="preserve">
<value>세로</value>
</data>
<data name="SettingsPageLeft.Content" xml:space="preserve">
<value>왼쪽</value>
</data>
<data name="SettingsPageLeftGapFactor.Header" xml:space="preserve">
<value>왼쪽 갭 영역 너비 계수</value>
</data>
@@ -1066,6 +1069,9 @@
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>원래 하이라이트 범위</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>왼쪽</value>
</data>
<data name="SettingsPageLyricsLight.Content" xml:space="preserve">
<value>빛</value>
</data>
@@ -1306,6 +1312,9 @@
<data name="SettingsPageRestart.Content" xml:space="preserve">
<value>변경 사항을 적용하려면 앱을 다시 시작하십시오</value>
</data>
<data name="SettingsPageRight.Content" xml:space="preserve">
<value>오른쪽</value>
</data>
<data name="SettingsPageRightGapFactor.Header" xml:space="preserve">
<value>오른쪽 간격 영역 너비 계수</value>
</data>
@@ -1393,12 +1402,6 @@
<data name="SettingsPageSongInfo.Text" xml:space="preserve">
<value>노래 정보</value>
</data>
<data name="SettingsPageLeft.Content" xml:space="preserve">
<value>왼쪽</value>
</data>
<data name="SettingsPageRight.Content" xml:space="preserve">
<value>오른쪽</value>
</data>
<data name="SettingsPageSongStatus.Header" xml:space="preserve">
<value>현재 노래</value>
</data>
@@ -1555,7 +1558,4 @@
<data name="UserGuide.Content" xml:space="preserve">
<value>사용 안내서</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>왼쪽</value>
</data>
</root>

View File

@@ -952,6 +952,9 @@
<data name="SettingsPageLayoutOrientationVertical.Content" xml:space="preserve">
<value>垂直</value>
</data>
<data name="SettingsPageLeft.Content" xml:space="preserve">
<value>靠左</value>
</data>
<data name="SettingsPageLeftGapFactor.Header" xml:space="preserve">
<value>左间隙区域宽度因子</value>
</data>
@@ -1066,6 +1069,9 @@
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>原文高亮显示范围</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>靠左</value>
</data>
<data name="SettingsPageLyricsLight.Content" xml:space="preserve">
<value>细体</value>
</data>
@@ -1306,6 +1312,9 @@
<data name="SettingsPageRestart.Content" xml:space="preserve">
<value>重启应用以应用更改</value>
</data>
<data name="SettingsPageRight.Content" xml:space="preserve">
<value>靠右</value>
</data>
<data name="SettingsPageRightGapFactor.Header" xml:space="preserve">
<value>右间隙区域宽度因子</value>
</data>
@@ -1393,12 +1402,6 @@
<data name="SettingsPageSongInfo.Text" xml:space="preserve">
<value>歌曲信息</value>
</data>
<data name="SettingsPageLeft.Content" xml:space="preserve">
<value>靠左</value>
</data>
<data name="SettingsPageRight.Content" xml:space="preserve">
<value>靠右</value>
</data>
<data name="SettingsPageSongStatus.Header" xml:space="preserve">
<value>当前歌曲</value>
</data>
@@ -1555,7 +1558,4 @@
<data name="UserGuide.Content" xml:space="preserve">
<value>使用指南</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>靠左</value>
</data>
</root>

View File

@@ -952,6 +952,9 @@
<data name="SettingsPageLayoutOrientationVertical.Content" xml:space="preserve">
<value>縱向</value>
</data>
<data name="SettingsPageLeft.Content" xml:space="preserve">
<value>靠左</value>
</data>
<data name="SettingsPageLeftGapFactor.Header" xml:space="preserve">
<value>左間隙區域寬度因子</value>
</data>
@@ -1066,6 +1069,9 @@
<data name="SettingsPageLyricsHighlightScope.Header" xml:space="preserve">
<value>原文高亮顯示範圍</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>靠左</value>
</data>
<data name="SettingsPageLyricsLight.Content" xml:space="preserve">
<value>細體</value>
</data>
@@ -1306,6 +1312,9 @@
<data name="SettingsPageRestart.Content" xml:space="preserve">
<value>重啟應用程式以應用更改</value>
</data>
<data name="SettingsPageRight.Content" xml:space="preserve">
<value>靠右</value>
</data>
<data name="SettingsPageRightGapFactor.Header" xml:space="preserve">
<value>右間隙區域寬度因子</value>
</data>
@@ -1393,12 +1402,6 @@
<data name="SettingsPageSongInfo.Text" xml:space="preserve">
<value>歌曲資訊</value>
</data>
<data name="SettingsPageLeft.Content" xml:space="preserve">
<value>靠左</value>
</data>
<data name="SettingsPageRight.Content" xml:space="preserve">
<value>靠右</value>
</data>
<data name="SettingsPageSongStatus.Header" xml:space="preserve">
<value>當前歌曲</value>
</data>
@@ -1555,7 +1558,4 @@
<data name="UserGuide.Content" xml:space="preserve">
<value>使用手冊</value>
</data>
<data name="SettingsPageLyricsLeft.Content" xml:space="preserve">
<value>靠左</value>
</data>
</root>

View File

@@ -75,7 +75,10 @@
<Grid.OpacityTransition>
<ScalarTransition Duration="{x:Bind const:Time.AnimationDuration}" />
</Grid.OpacityTransition>
<Grid x:Name="ShadowCastGrid" CornerRadius="{x:Bind AlbumArtCornerRadius, Mode=OneWay}">
<Grid
x:Name="ShadowCastGrid"
CornerRadius="{x:Bind AlbumArtCornerRadius, Mode=OneWay}"
SizeChanged="ShadowCastGrid_SizeChanged">
<Image x:Name="LastAlbumArtImage" Stretch="Uniform">
<Image.OpacityTransition>
<ScalarTransition Duration="{x:Bind const:Time.AnimationDuration}" />

View File

@@ -778,5 +778,9 @@ namespace BetterLyrics.WinUI3.Views
}
}
private void ShadowCastGrid_SizeChanged(object sender, SizeChangedEventArgs e)
{
UpdateAlbumArtCornerRadius();
}
}
}