feat: Provie settings to enable or disable word by word effect by force

This commit is contained in:
Zhe Fang
2025-11-13 19:51:55 -05:00
parent b44a29997b
commit f7f5e127a0
9 changed files with 57 additions and 10 deletions

View File

@@ -47,6 +47,10 @@
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsLyricsLineFadeEnabled, Mode=TwoWay}" />
</dev:SettingsCard>
<dev:SettingsCard x:Uid="SettingsPageForceWordByWordEffect" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE8F0;}">
<ToggleSwitch IsOn="{x:Bind LyricsEffectSettings.IsForceWordByWordEffect, Mode=TwoWay}" />
</dev:SettingsCard>
<!-- 高亮 -->
<dev:SettingsExpander x:Uid="SettingsPageLyricsHighlight" HeaderIcon="{ui:FontIcon FontFamily={StaticResource IconFontFamily}, Glyph=&#xE7E6;}">
<dev:SettingsExpander.Items>

View File

@@ -18,6 +18,7 @@ namespace BetterLyrics.WinUI3.Models
set => field = value;
}
public string WrappedOriginalText => string.Join(StringHelper.NewLine, LyricsLines.Select(line => line.OriginalText));
public bool IsWordByWord => LyricsLines.Any(x => x.LyricsChars.Count != 0);
public LyricsData()
{

View File

@@ -10,6 +10,8 @@ namespace BetterLyrics.WinUI3.Models.Settings
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsLineFadeEnabled { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsForceWordByWordEffect { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial bool IsLyricsGlowEffectEnabled { get; set; } = true;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial LineRenderingType LyricsGlowEffectScope { get; set; } = LineRenderingType.CurrentChar;
[ObservableProperty][NotifyPropertyChangedRecipients] public partial int LyricsGlowEffectAmount { get; set; } = 8;
@@ -60,6 +62,8 @@ namespace BetterLyrics.WinUI3.Models.Settings
IsLyricsLineFadeEnabled = this.IsLyricsLineFadeEnabled,
IsForceWordByWordEffect = this.IsForceWordByWordEffect,
IsLyricsGlowEffectEnabled = this.IsLyricsGlowEffectEnabled,
LyricsGlowEffectScope = this.LyricsGlowEffectScope,
LyricsGlowEffectAmount = this.LyricsGlowEffectAmount,

View File

@@ -799,6 +799,12 @@ If you encounter any problems, please go to the Settings page, About tab, and vi
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
<value>Force on top</value>
</data>
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
<value>Even if the current lyrics do not have word-by-word information, it will force it to simulate a word-by-word effect</value>
</data>
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
<value>Force enable word-by-word lyrics effect</value>
</data>
<data name="SettingsPageFPS.Header" xml:space="preserve">
<value>Rendering frame rate</value>
</data>

View File

@@ -799,6 +799,12 @@
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
<value>強制的に上に</value>
</data>
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
<value>現在の歌詞に単語ごとの情報がない場合でも、単語ごとの効果をシミュレートすることを余儀なくされます</value>
</data>
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
<value>単語ごとの歌詞効果を強制的に有効にします</value>
</data>
<data name="SettingsPageFPS.Header" xml:space="preserve">
<value>レンダリングフレームレート</value>
</data>

View File

@@ -799,6 +799,12 @@
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
<value>꼭대기에 강제로</value>
</data>
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
<value>현재 가사에 단어별 정보가 없더라도 단어별 효과를 강제로 시뮬레이션합니다</value>
</data>
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
<value>단어별 가사 효과 강제 사용</value>
</data>
<data name="SettingsPageFPS.Header" xml:space="preserve">
<value>렌더링 프레임 속도</value>
</data>

View File

@@ -799,6 +799,12 @@
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
<value>强制置于顶层</value>
</data>
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
<value>即使当前歌词没有逐字信息,也会迫使其模拟逐字效果</value>
</data>
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
<value>强制启用逐字歌词效果</value>
</data>
<data name="SettingsPageFPS.Header" xml:space="preserve">
<value>渲染帧率</value>
</data>

View File

@@ -799,6 +799,12 @@
<data name="SettingsPageForceAlwaysOnTop.Header" xml:space="preserve">
<value>強制置於頂層</value>
</data>
<data name="SettingsPageForceWordByWordEffect.Description" xml:space="preserve">
<value>即使目前的歌詞沒有逐字信息,也會迫使它模擬逐字效果</value>
</data>
<data name="SettingsPageForceWordByWordEffect.Header" xml:space="preserve">
<value>強制啟用逐字歌詞效果</value>
</data>
<data name="SettingsPageFPS.Header" xml:space="preserve">
<value>渲染幀率</value>
</data>

View File

@@ -328,21 +328,29 @@ namespace BetterLyrics.WinUI3.ViewModels.LyricsRendererViewModel
}
else
{
// 没有逐字时间轴,均匀分配每个字的高亮时间
int textLength = line.OriginalText.Length;
if (textLength == 0) return;
double lineProgress = (now - line.StartMs) / (lineEndMs - line.StartMs);
lineProgress = Math.Clamp(lineProgress, 0f, 1f);
if (_liveStatesService.LiveStates.LyricsWindowStatus.LyricsEffectSettings.IsForceWordByWordEffect)
{
// 没有逐字时间轴,均匀分配每个字的高亮时间
double lineProgress = (now - line.StartMs) / (lineEndMs - line.StartMs);
lineProgress = Math.Clamp(lineProgress, 0f, 1f);
// 计算当前高亮到第几个字
double charFloatIndex = lineProgress * textLength;
int charIndex = (int)charFloatIndex;
charStartIndex = Math.Clamp(charIndex, 0, textLength - 1);
charLength = 1;
// 计算当前高亮到第几个字
double charFloatIndex = lineProgress * textLength;
int charIndex = (int)charFloatIndex;
charStartIndex = Math.Clamp(charIndex, 0, textLength - 1);
charLength = 1;
// 当前字的进度0~1
charProgress = charFloatIndex - charIndex;
// 当前字的进度0~1
charProgress = charFloatIndex - charIndex;
}
else
{
charStartIndex = textLength;
charProgress = 1f;
}
}
}