This commit is contained in:
Zhe Fang
2025-11-29 21:46:24 -05:00
parent 47806c924d
commit 8e2c977a44
11 changed files with 147 additions and 449 deletions

View File

@@ -23,31 +23,6 @@
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
Text="Effect" />
<!-- 阴影 -->
<dev:SettingsExpander
x:Uid="SettingsPageLyricsShadow"
HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily},
Glyph=&#xF5EF;}"
IsExpanded="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageScope" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
<ComboBox SelectedIndex="{x:Bind LyricsEffectSettings.LyricsShadowScope, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}">
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeLineStartToCurrentChar" />
<ComboBoxItem x:Uid="SettingsPageLyricsRendingScopeCurrentLine" />
</ComboBox>
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageAmount" IsEnabled="{x:Bind LyricsEffectSettings.IsLyricsShadowEnabled, Mode=OneWay}">
<local:ExtendedSlider
Default="8"
Maximum="20"
Minimum="1"
Value="{x:Bind LyricsEffectSettings.LyricsShadowAmount, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<!-- 辉光效果 -->
<dev:SettingsCard x:Uid="SettingsPageLyricsGlowEffect" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE9A9;}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsGlowEffectEnabled, Mode=TwoWay}" />

View File

@@ -408,138 +408,6 @@
<ToggleSwitch IsOn="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.ShowLayoutIndicator, Mode=TwoWay}" />
</dev:SettingsCard>
<TextBlock x:Uid="SettingsPageGeneralLayoutFactor" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsCard x:Uid="SettingsPageLeftGapFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LeftGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageTopGapFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.TopGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageRightGapFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.RightGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageBottomGapFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.BottomGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<TextBlock x:Uid="SettingsPageHorizontalLayoutFactor" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsExpander x:Uid="SettingsPageTrackSummaryColFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.TrackSummaryColGapFactor, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageAlbumArtRowFacor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtRowGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageSongInfoRowFacor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.SongInfoRowGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsCard x:Uid="SettingsPageMiddleGapColFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MiddleColGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageLyricsColFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsColGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<TextBlock x:Uid="SettingsPageVerticalLayoutFactor" Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" />
<dev:SettingsExpander x:Uid="SettingsPageTrackSummaryRowFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.TrackSummaryRowGapFactor, Mode=TwoWay}" />
<dev:SettingsExpander.Items>
<dev:SettingsCard x:Uid="SettingsPageAlbumArtColFacor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtColGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageSongInfoColFacor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.SongInfoColGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
</dev:SettingsExpander.Items>
</dev:SettingsExpander>
<dev:SettingsCard x:Uid="SettingsPageMiddleGapRowFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.MiddleRowGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageLyricsRowFactor">
<NumberBox
LargeChange="10"
Minimum="1"
SmallChange="1"
SpinButtonPlacementMode="Inline"
Value="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.LyricsRowGapFactor, Mode=TwoWay}" />
</dev:SettingsCard>
</StackPanel>
</Grid>
</ScrollViewer>

View File

@@ -24,6 +24,7 @@ namespace BetterLyrics.WinUI3.Helper
public bool IsTransitioning => _isTransitioning;
public T Value => _currentValue;
public T StartValue => _startValue;
public T TargetValue => _targetValue;
public EasingType? EasingType => _easingType;

View File

@@ -78,9 +78,13 @@ namespace BetterLyrics.WinUI3.Logic
line.ScaleTransition.SetDelay(yScrollDelay);
line.ScaleTransition.StartTransition(_highlightedScale - distanceFactor * (_highlightedScale - _defaultScale));
line.OpacityTransition.SetDuration(yScrollDuration);
line.OpacityTransition.SetDelay(yScrollDelay);
line.OpacityTransition.StartTransition(absLineCountDelta == 0 ? 1 : (1 - distanceFactor) * 0.3);
line.UnplayingOpacityTransition.SetDuration(yScrollDuration);
line.UnplayingOpacityTransition.SetDelay(yScrollDelay);
line.UnplayingOpacityTransition.StartTransition(absLineCountDelta == 0 ? 0.3 : (1 - distanceFactor) * 0.3);
line.PlayingOpacityTransition.SetDuration(yScrollDuration);
line.PlayingOpacityTransition.SetDelay(yScrollDelay);
line.PlayingOpacityTransition.StartTransition(absLineCountDelta == 0 ? 1 : (1 - distanceFactor) * 0.3);
line.ColorTransition.SetDuration(yScrollDuration);
line.ColorTransition.SetDelay(yScrollDelay);
@@ -101,7 +105,8 @@ namespace BetterLyrics.WinUI3.Logic
line.AngleTransition.Update(elapsedTime);
line.ScaleTransition.Update(elapsedTime);
line.BlurAmountTransition.Update(elapsedTime);
line.OpacityTransition.Update(elapsedTime);
line.PlayingOpacityTransition.Update(elapsedTime);
line.UnplayingOpacityTransition.Update(elapsedTime);
line.YOffsetTransition.Update(elapsedTime);
line.ColorTransition.Update(elapsedTime);
}

View File

@@ -19,7 +19,8 @@ namespace BetterLyrics.WinUI3.Models
public double AnimationDuration { get; set; } = 0.3;
public ValueTransition<double> AngleTransition { get; set; }
public ValueTransition<double> BlurAmountTransition { get; set; }
public ValueTransition<double> OpacityTransition { get; set; }
public ValueTransition<double> UnplayingOpacityTransition { get; set; }
public ValueTransition<double> PlayingOpacityTransition { get; set; }
public ValueTransition<double> ScaleTransition { get; set; }
public ValueTransition<double> YOffsetTransition { get; set; }
public ValueTransition<Color> ColorTransition { get; set; }
@@ -89,7 +90,12 @@ namespace BetterLyrics.WinUI3.Models
durationSeconds: AnimationDuration,
easingType: EasingType.EaseInOutSine
);
OpacityTransition = new(
UnplayingOpacityTransition = new(
initialValue: 0,
durationSeconds: AnimationDuration,
easingType: EasingType.EaseInOutSine
);
PlayingOpacityTransition = new(
initialValue: 0,
durationSeconds: AnimationDuration,
easingType: EasingType.EaseInOutSine

View File

@@ -42,27 +42,6 @@ namespace BetterLyrics.WinUI3.Models
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double WindowWidth { get; set; } = 800;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double WindowHeight { get; set; } = 500;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double LeftGapFactor { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double TopGapFactor { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double RightGapFactor { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double BottomGapFactor { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double MiddleColGapFactor { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double MiddleRowGapFactor { get; set; } = 12;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double TrackSummaryColGapFactor { get; set; } = 38;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double TrackSummaryRowGapFactor { get; set; } = 19;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double LyricsColGapFactor { get; set; } = 38;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double LyricsRowGapFactor { get; set; } = 57;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double AlbumArtColGapFactor { get; set; } = 4;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double AlbumArtRowGapFactor { get; set; } = 4;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double SongInfoColGapFactor { get; set; } = 1;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial double SongInfoRowGapFactor { get; set; } = 1;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool ShowLayoutIndicator { get; set; } = false;
public LyricsWindowStatus()
@@ -221,26 +200,6 @@ namespace BetterLyrics.WinUI3.Models
WindowY = this.WindowY,
WindowWidth = this.WindowWidth,
WindowHeight = this.WindowHeight,
LeftGapFactor = this.LeftGapFactor,
TopGapFactor = this.TopGapFactor,
RightGapFactor = this.RightGapFactor,
BottomGapFactor = this.BottomGapFactor,
MiddleColGapFactor = this.MiddleColGapFactor,
MiddleRowGapFactor = this.MiddleRowGapFactor,
TrackSummaryColGapFactor = this.TrackSummaryColGapFactor,
TrackSummaryRowGapFactor = this.TrackSummaryRowGapFactor,
AlbumArtColGapFactor = this.AlbumArtColGapFactor,
AlbumArtRowGapFactor = this.AlbumArtRowGapFactor,
SongInfoColGapFactor = this.SongInfoColGapFactor,
SongInfoRowGapFactor = this.SongInfoRowGapFactor,
LyricsColGapFactor = this.LyricsColGapFactor,
LyricsRowGapFactor = this.LyricsRowGapFactor,
};
}

View File

@@ -7,13 +7,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
public partial class LyricsEffectSettings : ObservableRecipient, ICloneable
{
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsGlowEffectEnabled { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsScaleEffectEnabled { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsShadowEnabled { get; set; } = false;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LineRenderingType LyricsShadowScope { get; set; } = LineRenderingType.LineStartToCurrentChar;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsShadowAmount { get; set; } = 8;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsFloatAnimationEnabled { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial EasingType LyricsScrollEasingType { get; set; }
@@ -45,13 +39,7 @@ namespace BetterLyrics.WinUI3.Models.Settings
return new LyricsEffectSettings(this.LyricsScrollTopDuration, this.LyricsScrollDuration, this.LyricsScrollBottomDuration, this.LyricsScrollEasingType)
{
IsLyricsGlowEffectEnabled = this.IsLyricsGlowEffectEnabled,
IsLyricsScaleEffectEnabled = this.IsLyricsScaleEffectEnabled,
IsLyricsShadowEnabled = this.IsLyricsShadowEnabled,
LyricsShadowScope = this.LyricsShadowScope,
LyricsShadowAmount = this.LyricsShadowAmount,
IsLyricsFloatAnimationEnabled = this.IsLyricsFloatAnimationEnabled,
LyricsScrollEasingType = this.LyricsScrollEasingType,

View File

@@ -7,6 +7,8 @@ using Microsoft.Graphics.Canvas.Effects;
using Microsoft.Graphics.Canvas.Text;
using Microsoft.Graphics.Canvas.UI.Xaml;
using Microsoft.UI;
using Microsoft.UI.Composition;
using Microsoft.UI.Xaml.Media;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -39,7 +41,7 @@ namespace BetterLyrics.WinUI3.Renderer
{
if (line.PhoneticCanvasTextLayout == null) return;
var opacity = line.OpacityTransition.Value * 0.3;
var opacity = line.UnplayingOpacityTransition.Value;
var blur = line.BlurAmountTransition.Value;
var bounds = line.PhoneticCanvasTextLayout.LayoutBounds;
@@ -50,22 +52,26 @@ namespace BetterLyrics.WinUI3.Renderer
bounds.Height
);
using (var blurEffect = new GaussianBlurEffect
using (var opacityLayer = ds.CreateLayer((float)opacity))
{
BlurAmount = (float)blur,
Source = source,
BorderMode = EffectBorderMode.Soft
})
{
ds.DrawImage(blurEffect, destRect, destRect, (float)opacity);
using (var blurEffect = new GaussianBlurEffect
{
BlurAmount = (float)blur,
Source = source,
BorderMode = EffectBorderMode.Soft
})
{
ds.DrawImage(blurEffect);
}
}
}
private void DrawTranslated(CanvasDrawingSession ds, ICanvasImage source, LyricsLine line)
{
if (line.TranslatedCanvasTextLayout == null) return;
var opacity = line.OpacityTransition.Value * 0.3;
var opacity = line.UnplayingOpacityTransition.Value;
var blur = line.BlurAmountTransition.Value;
var bounds = line.TranslatedCanvasTextLayout.LayoutBounds;
@@ -76,14 +82,17 @@ namespace BetterLyrics.WinUI3.Renderer
bounds.Height
);
using (var blurEffect = new GaussianBlurEffect
using (var opacityLayer = ds.CreateLayer((float)opacity))
{
BlurAmount = (float)blur,
Source = source,
BorderMode = EffectBorderMode.Soft
})
{
ds.DrawImage(blurEffect, destRect, destRect, (float)opacity);
using (var blurEffect = new GaussianBlurEffect
{
BlurAmount = (float)blur,
Source = source,
BorderMode = EffectBorderMode.Soft
})
{
ds.DrawImage(blurEffect);
}
}
}
@@ -99,8 +108,6 @@ namespace BetterLyrics.WinUI3.Renderer
{
if (line.OriginalCanvasTextLayout == null) return;
var opacity = line.OpacityTransition.Value;
var curCharIndex = state.SyllableStartIndex + state.SyllableLength * state.SyllableProgress;
float fadeWidth = (1f / Math.Max(1, line.OriginalText.Length)) * 0.5f;
@@ -108,7 +115,7 @@ namespace BetterLyrics.WinUI3.Renderer
foreach (var subLineRegion in lineRegions)
{
DrawSubLineRegion(resourceCreator, ds, source, line, subLineRegion, curCharIndex, fadeWidth, opacity, bgColor, fgColor, state, settings);
DrawSubLineRegion(resourceCreator, ds, source, line, subLineRegion, curCharIndex, fadeWidth, bgColor, fgColor, state, settings);
}
}
@@ -120,13 +127,14 @@ namespace BetterLyrics.WinUI3.Renderer
CanvasTextLayoutRegion subLineRegion,
double curCharIndex,
float fadeWidth,
double opacity,
Color bgColor,
Color fgColor,
LinePlaybackState state,
LyricsEffectSettings settings)
{
var blur = line.BlurAmountTransition.Value;
var playingOpacity = line.PlayingOpacityTransition.Value;
var unplayingOpacity = line.UnplayingOpacityTransition.Value;
var subLineLayoutBounds = subLineRegion.LayoutBounds;
Rect subLineRect = new(
@@ -136,17 +144,17 @@ namespace BetterLyrics.WinUI3.Renderer
subLineLayoutBounds.Height
);
using (var maskLayer = new CanvasCommandList(resourceCreator))
using (var gradientLayer = new CanvasCommandList(resourceCreator))
{
using (var maskLayerDs = maskLayer.CreateDrawingSession())
using (var gradientLayerDs = gradientLayer.CreateDrawingSession())
{
float progressInRegion = (float)((curCharIndex - subLineRegion.CharacterIndex) / subLineRegion.CharacterCount);
progressInRegion = Math.Clamp(progressInRegion, 0, 1 + fadeWidth);
var stop1 = fgColor.WithAlpha((byte)(255 * opacity));
var stop2 = bgColor.WithAlpha((byte)(255 * Math.Min(0.3, opacity)));
var stop1 = fgColor.WithAlpha((byte)(255 * playingOpacity));
var stop2 = bgColor.WithAlpha((byte)(255 * unplayingOpacity));
using (var maskBrush = new CanvasLinearGradientBrush(resourceCreator,
using (var gradientBrush = new CanvasLinearGradientBrush(resourceCreator,
[
new CanvasGradientStop { Position = 0, Color = stop1 },
new CanvasGradientStop { Position = progressInRegion, Color = stop1 },
@@ -154,34 +162,22 @@ namespace BetterLyrics.WinUI3.Renderer
new CanvasGradientStop { Position = 1 + fadeWidth, Color = stop2 }
]))
{
maskBrush.StartPoint = new Vector2((float)subLineRect.X, (float)subLineRect.Y);
maskBrush.EndPoint = new Vector2((float)(subLineRect.X + subLineRect.Width), (float)subLineRect.Y);
maskLayerDs.FillRectangle(subLineRect, maskBrush);
gradientBrush.StartPoint = new Vector2((float)subLineRect.X, (float)subLineRect.Y);
gradientBrush.EndPoint = new Vector2((float)(subLineRect.X + subLineRect.Width), (float)subLineRect.Y);
gradientLayerDs.FillRectangle(subLineRect, gradientBrush);
}
}
using var cropEffect = new CropEffect
{
Source = source,
SourceRectangle = subLineRect,
BorderMode = EffectBorderMode.Soft
};
using (var textWithColorLayer = new CompositeEffect
{
Mode = CanvasComposite.DestinationIn,
Sources = { maskLayer, cropEffect }
})
using (var textWithBlurLayer = new GaussianBlurEffect
{
Source = textWithColorLayer,
BorderMode = EffectBorderMode.Soft,
BlurAmount = (float)blur,
Sources = { gradientLayer, source }
})
{
int endCharIndex = subLineRegion.CharacterIndex + subLineRegion.CharacterCount;
for (int i = subLineRegion.CharacterIndex; i < endCharIndex; i++)
{
DrawSingleCharacter(ds, line, i, curCharIndex, textWithBlurLayer, state, settings);
DrawSingleCharacter(ds, line, i, curCharIndex, textWithColorLayer, state, settings);
}
}
}
@@ -192,7 +188,7 @@ namespace BetterLyrics.WinUI3.Renderer
LyricsLine line,
int charIndex,
double exactProgressIndex,
ICanvasImage maskedSource,
ICanvasImage source,
LinePlaybackState state,
LyricsEffectSettings settings)
{
@@ -215,6 +211,8 @@ namespace BetterLyrics.WinUI3.Renderer
double scale = 1;
double glow = 0;
bool drawGlow = false;
if (settings.IsLyricsFloatAnimationEnabled)
{
double targetFloatOffset = sourceCharRect.Height * 0.05;
@@ -238,6 +236,7 @@ namespace BetterLyrics.WinUI3.Renderer
if (settings.IsLyricsGlowEffectEnabled)
{
glow = Math.Sin(state.SyllableProgress * Math.PI) * sourceCharRect.Height * 0.2;
drawGlow = true;
}
}
@@ -245,20 +244,22 @@ namespace BetterLyrics.WinUI3.Renderer
using (var singleCharCrop = new CropEffect
{
Source = maskedSource,
Source = source,
SourceRectangle = sourceCharRect,
BorderMode = EffectBorderMode.Soft
})
{
// 这里不做 glow > 0 的判断而总是加入辉光效果是为了平滑不断层
using (var glowEffect = new GaussianBlurEffect
if (drawGlow)
{
Source = singleCharCrop,
BlurAmount = (float)glow,
BorderMode = EffectBorderMode.Soft
})
{
ds.DrawImage(glowEffect, destCharRect.Extend(sourceCharRect.Height), sourceCharRect.Extend(sourceCharRect.Height));
using (var glowEffect = new GaussianBlurEffect
{
Source = singleCharCrop,
BlurAmount = (float)glow,
BorderMode = EffectBorderMode.Soft
})
{
ds.DrawImage(glowEffect, destCharRect.Extend(sourceCharRect.Height), sourceCharRect.Extend(sourceCharRect.Height));
}
}
ds.DrawImage(singleCharCrop, destCharRect, sourceCharRect);

View File

@@ -15,19 +15,28 @@ namespace BetterLyrics.WinUI3.Renderer
LyricsLine line)
{
var blurAmount = (float)line.BlurAmountTransition.Value;
var opacity = line.OpacityTransition.Value;
if (line.PhoneticCanvasTextLayout != null)
{
var opacity = line.UnplayingOpacityTransition.Value;
DrawPart(ds, textOnlyLayer,
line.PhoneticCanvasTextLayout,
line.PhoneticPosition,
blurAmount,
(float)opacity * 0.3f);
(float)opacity);
}
if (line.OriginalCanvasTextLayout != null)
{
double opacity;
if (line.PlayingOpacityTransition.StartValue > line.UnplayingOpacityTransition.StartValue)
{
opacity = line.PlayingOpacityTransition.Value;
}
else
{
opacity = line.UnplayingOpacityTransition.Value;
}
DrawPart(ds, textOnlyLayer,
line.OriginalCanvasTextLayout,
line.OriginalPosition,
@@ -37,11 +46,12 @@ namespace BetterLyrics.WinUI3.Renderer
if (line.TranslatedCanvasTextLayout != null)
{
var opacity = line.UnplayingOpacityTransition.Value;
DrawPart(ds, textOnlyLayer,
line.TranslatedCanvasTextLayout,
line.TranslatedPosition,
blurAmount,
(float)opacity * 0.3f);
(float)opacity);
}
}

View File

@@ -31,18 +31,18 @@
<Grid x:Name="TrackSummaryGridContainer" Loaded="TrackSummaryGridContainer_Loaded">
<Grid.RowDefinitions>
<RowDefinition x:Name="TopGapDef" Height="*" />
<RowDefinition x:Name="TopGapDef" Height="0" />
<RowDefinition x:Name="TrackSummaryRowDef" Height="*" />
<RowDefinition x:Name="MiddleGapRowDef" Height="*" />
<RowDefinition x:Name="LyricsRowDef" Height="*" />
<RowDefinition x:Name="BottomGapDef" Height="*" />
<RowDefinition x:Name="MiddleGapRowDef" Height="0" />
<RowDefinition x:Name="LyricsRowDef" Height="4*" />
<RowDefinition x:Name="BottomGapDef" Height="0" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftGapDef" Width="*" />
<ColumnDefinition x:Name="LeftGapDef" Width="0" />
<ColumnDefinition x:Name="TrackSummaryColDef" Width="*" />
<ColumnDefinition x:Name="MiddleGapColDef" Width="*" />
<ColumnDefinition x:Name="MiddleGapColDef" Width="0" />
<ColumnDefinition x:Name="LyricsColDef" Width="*" />
<ColumnDefinition x:Name="RightGapDef" Width="*" />
<ColumnDefinition x:Name="RightGapDef" Width="0" />
</Grid.ColumnDefinitions>
<!-- Album art and song info area -->
@@ -50,14 +50,19 @@
x:Name="TrackSummaryGrid"
Grid.Row="1"
Grid.Column="1"
VerticalAlignment="Center"
SizeChanged="TrackSummaryGrid_SizeChanged">
<Grid.RowDefinitions>
<RowDefinition x:Name="AlbumArtRowDef" Height="*" />
<RowDefinition x:Name="SongInfoRowDef" Height="*" />
<RowDefinition x:Name="TrackSummaryGridRow0" Height="0" />
<RowDefinition x:Name="TrackSummaryGridRow1" Height="*" />
<RowDefinition x:Name="TrackSummaryGridRow2" Height="0" />
<RowDefinition x:Name="TrackSummaryGridRow3" Height="Auto" />
<RowDefinition x:Name="TrackSummaryGridRow4" Height="0" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="AlbumArtColDef" Width="*" />
<ColumnDefinition x:Name="SongInfoColDef" Width="*" />
<ColumnDefinition x:Name="TrackSummaryGridCol0" Width="Auto" />
<ColumnDefinition x:Name="TrackSummaryGridCol1" Width="0" />
<ColumnDefinition x:Name="TrackSummaryGridCol2" Width="*" />
</Grid.ColumnDefinitions>
<Grid.OpacityTransition>
<ScalarTransition Duration="{x:Bind const:Time.AnimationDuration}" />
@@ -66,7 +71,6 @@
<!-- Album art -->
<Grid
x:Name="AlbumArtGrid"
Grid.Row="0"
Margin="-32"
Padding="32"
HorizontalAlignment="{x:Bind ViewModel.LiveStates.LyricsWindowStatus.AlbumArtLayoutSettings.AlbumArtAlignmentType, Mode=OneWay}">
@@ -206,24 +210,6 @@
<ColumnDefinition Width="{Binding ElementName=RightGapDef, Path=Width, Mode=OneWay}" />
</Grid.ColumnDefinitions>
<!-- 通用指示器 -->
<Grid
Grid.Row="0"
Grid.ColumnSpan="5"
Background="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}" />
<Grid
Grid.Row="4"
Grid.ColumnSpan="5"
Background="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}" />
<Grid
Grid.RowSpan="5"
Grid.Column="0"
Background="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}" />
<Grid
Grid.RowSpan="5"
Grid.Column="4"
Background="{ThemeResource SystemControlBackgroundBaseMediumLowBrush}" />
<!-- 垂直布局指示器 -->
<Grid
Grid.Row="1"

View File

@@ -8,21 +8,17 @@ using BetterLyrics.WinUI3.Models;
using BetterLyrics.WinUI3.Models.Settings;
using BetterLyrics.WinUI3.Services.LiveStatesService;
using BetterLyrics.WinUI3.Services.MediaSessionsService;
using BetterLyrics.WinUI3.Services.SettingsService;
using BetterLyrics.WinUI3.ViewModels;
using CommunityToolkit.Mvvm.DependencyInjection;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.Mvvm.Messaging.Messages;
using CommunityToolkit.WinUI;
using DevWinUI;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Documents;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Media.Imaging;
using System;
using System.Diagnostics;
using System.Numerics;
using System.Threading.Tasks;
@@ -32,7 +28,6 @@ namespace BetterLyrics.WinUI3.Views
IRecipient<PropertyChangedMessage<int>>,
IRecipient<PropertyChangedMessage<bool>>,
IRecipient<PropertyChangedMessage<string>>,
IRecipient<PropertyChangedMessage<double>>,
IRecipient<PropertyChangedMessage<SongInfo?>>,
IRecipient<PropertyChangedMessage<BitmapImage?>>,
IRecipient<PropertyChangedMessage<LyricsLayoutOrientation>>,
@@ -77,7 +72,6 @@ namespace BetterLyrics.WinUI3.Views
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<BitmapImage?>>(this);
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<LyricsLayoutOrientation>>(this);
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<LyricsDisplayType>>(this);
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<double>>(this);
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<AlbumArtThemeColors>>(this);
WeakReferenceMessenger.Default.Register<PropertyChangedMessage<LyricsWindowStatus>>(this);
}
@@ -235,15 +229,15 @@ namespace BetterLyrics.WinUI3.Views
switch (status.LyricsLayoutOrientation)
{
case LyricsLayoutOrientation.Horizontal:
Grid.SetRow(SongInfoStackPanel, 1);
Grid.SetColumn(SongInfoStackPanel, 0);
Grid.SetRow(SongInfoStackPanel, 3);
Grid.SetRowSpan(SongInfoStackPanel, 1);
Grid.SetColumnSpan(SongInfoStackPanel, 2);
Grid.SetColumn(SongInfoStackPanel, 0);
Grid.SetColumnSpan(SongInfoStackPanel, 3);
break;
case LyricsLayoutOrientation.Vertical:
Grid.SetRow(SongInfoStackPanel, 0);
Grid.SetColumn(SongInfoStackPanel, 1);
Grid.SetRowSpan(SongInfoStackPanel, 2);
Grid.SetRowSpan(SongInfoStackPanel, 5);
Grid.SetColumn(SongInfoStackPanel, 2);
Grid.SetColumnSpan(SongInfoStackPanel, 1);
break;
default:
@@ -259,11 +253,15 @@ namespace BetterLyrics.WinUI3.Views
switch (status.LyricsLayoutOrientation)
{
case LyricsLayoutOrientation.Horizontal:
Grid.SetRow(AlbumArtGrid, 1);
Grid.SetRowSpan(AlbumArtGrid, 1);
Grid.SetColumnSpan(AlbumArtGrid, 2);
Grid.SetColumn(AlbumArtGrid, 0);
Grid.SetColumnSpan(AlbumArtGrid, 3);
break;
case LyricsLayoutOrientation.Vertical:
Grid.SetRowSpan(AlbumArtGrid, 2);
Grid.SetRow(AlbumArtGrid, 0);
Grid.SetRowSpan(AlbumArtGrid, 5);
Grid.SetColumn(AlbumArtGrid, 0);
Grid.SetColumnSpan(AlbumArtGrid, 1);
break;
default:
@@ -347,64 +345,49 @@ namespace BetterLyrics.WinUI3.Views
UpdateAlbumArtCornerRadius();
}
private void WriteGapFactor()
{
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
status.LeftGapFactor = LeftGapDef.Width.Value;
status.TopGapFactor = TopGapDef.Height.Value;
status.RightGapFactor = RightGapDef.Width.Value;
status.BottomGapFactor = BottomGapDef.Height.Value;
status.TrackSummaryColGapFactor = TrackSummaryColDef.Width.Value;
status.MiddleColGapFactor = MiddleGapColDef.Width.Value;
status.LyricsColGapFactor = LyricsColDef.Width.Value;
status.TrackSummaryRowGapFactor = TrackSummaryRowDef.Height.Value;
status.MiddleRowGapFactor = MiddleGapRowDef.Height.Value;
status.LyricsRowGapFactor = LyricsRowDef.Height.Value;
status.AlbumArtColGapFactor = AlbumArtColDef.Width.Value;
status.SongInfoColGapFactor = SongInfoColDef.Width.Value;
status.AlbumArtRowGapFactor = AlbumArtRowDef.Height.Value;
status.SongInfoRowGapFactor = SongInfoRowDef.Height.Value;
}
private void ReadGapFactor()
{
var status = _liveStatesService.LiveStates.LyricsWindowStatus;
LeftGapDef.Width = new(status.LeftGapFactor, GridUnitType.Star);
TopGapDef.Height = new(status.TopGapFactor, GridUnitType.Star);
RightGapDef.Width = new(status.RightGapFactor, GridUnitType.Star);
BottomGapDef.Height = new(status.BottomGapFactor, GridUnitType.Star);
MiddleGapColDef.Width = new(status.MiddleColGapFactor, GridUnitType.Star);
MiddleGapRowDef.Height = new(status.MiddleRowGapFactor, GridUnitType.Star);
TrackSummaryColDef.Width = new(status.TrackSummaryColGapFactor, GridUnitType.Star);
TrackSummaryRowDef.Height = new(status.TrackSummaryRowGapFactor, GridUnitType.Star);
LyricsColDef.Width = new(status.LyricsColGapFactor, GridUnitType.Star);
LyricsRowDef.Height = new(status.LyricsRowGapFactor, GridUnitType.Star);
AlbumArtColDef.Width = new(status.AlbumArtColGapFactor, GridUnitType.Star);
SongInfoColDef.Width = new(status.SongInfoColGapFactor, GridUnitType.Star);
AlbumArtRowDef.Height = new(status.AlbumArtRowGapFactor, GridUnitType.Star);
SongInfoRowDef.Height = new(status.SongInfoRowGapFactor, GridUnitType.Star);
}
// ====
private void RootGrid_SizeChanged(object sender, SizeChangedEventArgs e)
{
RenderSongInfo();
var width = e.NewSize.Width;
var height = e.NewSize.Height;
double xMargin = 0;
double yMargin = 0;
double middleGapCol = 0;
double gapBetweenAlbumArtAndSongInfo = 0;
if (height < 400)
{
middleGapCol = Math.Max(16, height * 0.1);
}
else
{
middleGapCol = Math.Max(16, width * 0.1);
}
if (height < 100)
{
gapBetweenAlbumArtAndSongInfo = 0;
}
else
{
gapBetweenAlbumArtAndSongInfo = GetTitleFontSize() / 2;
}
xMargin = Math.Max(16, width * 0.1);
yMargin = Math.Max(16, height * 0.15);
LeftGapDef.Width = RightGapDef.Width = new(xMargin);
MiddleGapColDef.Width = new(middleGapCol);
TrackSummaryGridRow0.Height = TrackSummaryGridRow4.Height = new(yMargin);
TrackSummaryGridRow2.Height = new(gapBetweenAlbumArtAndSongInfo);
RenderSongInfo();
OnLayoutChanged();
if (e.NewSize.Width < 500 || e.NewSize.Height < 100)
if (width < 500 || height < 100)
{
if (BottomCommandGrid.Children.Count != 0)
{
@@ -751,88 +734,6 @@ namespace BetterLyrics.WinUI3.Views
}
}
public void Receive(PropertyChangedMessage<double> message)
{
if (message.Sender is LyricsWindowStatus)
{
// ====
if (message.PropertyName == nameof(LyricsWindowStatus.LeftGapFactor))
{
LeftGapDef.Width = new(_liveStatesService.LiveStates.LyricsWindowStatus.LeftGapFactor, GridUnitType.Star);
}
else if (message.PropertyName == nameof(LyricsWindowStatus.TopGapFactor))
{
TopGapDef.Height = new(_liveStatesService.LiveStates.LyricsWindowStatus.TopGapFactor, GridUnitType.Star);
}
else if (message.PropertyName == nameof(LyricsWindowStatus.RightGapFactor))
{
RightGapDef.Width = new(_liveStatesService.LiveStates.LyricsWindowStatus.RightGapFactor, GridUnitType.Star);
}
else if (message.PropertyName == nameof(LyricsWindowStatus.BottomGapFactor))
{
BottomGapDef.Height = new(_liveStatesService.LiveStates.LyricsWindowStatus.BottomGapFactor, GridUnitType.Star);
}
// ====
else if (message.PropertyName == nameof(LyricsWindowStatus.MiddleColGapFactor))
{
MiddleGapColDef.Width = new(_liveStatesService.LiveStates.LyricsWindowStatus.MiddleColGapFactor, GridUnitType.Star);
}
else if (message.PropertyName == nameof(LyricsWindowStatus.MiddleRowGapFactor))
{
MiddleGapRowDef.Height = new(_liveStatesService.LiveStates.LyricsWindowStatus.MiddleRowGapFactor, GridUnitType.Star);
}
// ====
else if (message.PropertyName == nameof(LyricsWindowStatus.TrackSummaryColGapFactor))
{
TrackSummaryColDef.Width = new(_liveStatesService.LiveStates.LyricsWindowStatus.TrackSummaryColGapFactor, GridUnitType.Star);
}
else if (message.PropertyName == nameof(LyricsWindowStatus.TrackSummaryRowGapFactor))
{
TrackSummaryRowDef.Height = new(_liveStatesService.LiveStates.LyricsWindowStatus.TrackSummaryRowGapFactor, GridUnitType.Star);
}
// ====
else if (message.PropertyName == nameof(LyricsWindowStatus.LyricsColGapFactor))
{
LyricsColDef.Width = new(_liveStatesService.LiveStates.LyricsWindowStatus.LyricsColGapFactor, GridUnitType.Star);
}
else if (message.PropertyName == nameof(LyricsWindowStatus.LyricsRowGapFactor))
{
LyricsRowDef.Height = new(_liveStatesService.LiveStates.LyricsWindowStatus.LyricsRowGapFactor, GridUnitType.Star);
}
// ====
else if (message.PropertyName == nameof(LyricsWindowStatus.AlbumArtColGapFactor))
{
AlbumArtColDef.Width = new(_liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtColGapFactor, GridUnitType.Star);
}
else if (message.PropertyName == nameof(LyricsWindowStatus.AlbumArtRowGapFactor))
{
AlbumArtRowDef.Height = new(_liveStatesService.LiveStates.LyricsWindowStatus.AlbumArtRowGapFactor, GridUnitType.Star);
}
// ====
else if (message.PropertyName == nameof(LyricsWindowStatus.SongInfoColGapFactor))
{
SongInfoColDef.Width = new(_liveStatesService.LiveStates.LyricsWindowStatus.SongInfoColGapFactor, GridUnitType.Star);
}
else if (message.PropertyName == nameof(LyricsWindowStatus.SongInfoRowGapFactor))
{
SongInfoRowDef.Height = new(_liveStatesService.LiveStates.LyricsWindowStatus.SongInfoRowGapFactor, GridUnitType.Star);
}
}
}
public void Receive(PropertyChangedMessage<AlbumArtThemeColors> message)
{
if (message.Sender is IMediaSessionsService)
@@ -851,8 +752,6 @@ namespace BetterLyrics.WinUI3.Views
if (message.PropertyName == nameof(LiveStates.LyricsWindowStatus))
{
OnLayoutChanged();
ReadGapFactor();
}
}
}