Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(synced-lyrics): Better-Lyrics Styling for Synced-Lyrics #2554

Merged
merged 5 commits into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/i18n/resources/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,10 @@
"line-effect": {
"label": "Line effect",
"submenu": {
"fancy": {
"label": "Fancy",
"tooltip": "Use large, app-like effects on the current line"
},
"focus": {
"label": "Focus",
"tooltip": "Make only the current line white"
Expand Down
6 changes: 3 additions & 3 deletions src/plugins/synced-lyrics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { SyncedLyricsPluginConfig } from './types';
export default createPlugin({
name: () => t('plugins.synced-lyrics.name'),
description: () => t('plugins.synced-lyrics.description'),
authors: ['Non0reo', 'ArjixWasTaken'],
authors: ['Non0reo', 'ArjixWasTaken', 'KimJammer'],
restartNeeded: true,
addedVersion: '3.5.X',
config: {
Expand All @@ -19,8 +19,8 @@ export default createPlugin({
showLyricsEvenIfInexact: true,
showTimeCodes: false,
defaultTextString: '♪',
lineEffect: 'scale',
} as SyncedLyricsPluginConfig,
lineEffect: 'fancy',
} satisfies SyncedLyricsPluginConfig,

menu,
renderer,
Expand Down
21 changes: 18 additions & 3 deletions src/plugins/synced-lyrics/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { t } from '@/i18n';
import type { MenuContext } from '@/types/contexts';
import type { SyncedLyricsPluginConfig } from './types';

export const menu = async (ctx: MenuContext<SyncedLyricsPluginConfig>): Promise<
MenuItemConstructorOptions[]
> => {
export const menu = async (
ctx: MenuContext<SyncedLyricsPluginConfig>,
): Promise<MenuItemConstructorOptions[]> => {
const config = await ctx.getConfig();

return [
Expand All @@ -27,6 +27,21 @@ export const menu = async (ctx: MenuContext<SyncedLyricsPluginConfig>): Promise<
toolTip: t('plugins.synced-lyrics.menu.line-effect.tooltip'),
type: 'submenu',
submenu: [
{
label: t(
'plugins.synced-lyrics.menu.line-effect.submenu.fancy.label',
),
toolTip: t(
'plugins.synced-lyrics.menu.line-effect.submenu.fancy.tooltip',
),
type: 'radio',
checked: config.lineEffect === 'fancy',
click() {
ctx.setConfig({
lineEffect: 'fancy',
});
},
},
{
label: t(
'plugins.synced-lyrics.menu.line-effect.submenu.scale.label',
Expand Down
48 changes: 38 additions & 10 deletions src/plugins/synced-lyrics/renderer/components/SyncedLine.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createEffect, createMemo } from 'solid-js';
import { createEffect, createMemo, For } from 'solid-js';

import { currentTime } from './LyricsContainer';

Expand Down Expand Up @@ -32,7 +32,16 @@ export const SyncedLine = ({ line }: SyncedLineProps) => {
return config()?.defaultTextString ?? '';
});

// prettier-ignore
if (!text()) {
return (
<yt-formatted-string
text={{
runs: [{ text: '' }],
}}
/>
);
}

return (
<div
ref={ref}
Expand All @@ -41,14 +50,33 @@ export const SyncedLine = ({ line }: SyncedLineProps) => {
_ytAPI?.seekTo(line.timeInMs / 1000);
}}
>
<yt-formatted-string
class="text-lyrics description ytmusic-description-shelf-renderer"
text={{
runs: [
{ text: config()?.showTimeCodes ? `[${line.time}]` : '' },
{ text: text() }],
}}
/>
<div class="text-lyrics description ytmusic-description-shelf-renderer">
<yt-formatted-string
text={{
runs: [{ text: config()?.showTimeCodes ? `[${line.time}] ` : '' }],
}}
/>

<For each={text().split(' ')}>
{(word, index) => {
return (
<span
style={{
'transition-delay': `${index() * 0.05}s`,
'animation-delay': `${index() * 0.05}s`,
'--lyrics-duration:': `${line.duration / 1000}s;`,
}}
>
<yt-formatted-string
text={{
runs: [{ text: `${word} ` }],
}}
/>
</span>
);
}}
</For>
</div>
</div>
);
};
86 changes: 68 additions & 18 deletions src/plugins/synced-lyrics/renderer/renderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,85 @@ createEffect(() => {

// Set the line effect
switch (config()?.lineEffect) {
case 'fancy':
root.style.setProperty('--lyrics-font-size', '3rem');
root.style.setProperty('--lyrics-line-height', '1.333');
root.style.setProperty('--lyrics-width', '100%');
root.style.setProperty('--lyrics-padding', '2rem');
root.style.setProperty(
'--lyrics-animations',
'lyrics-glow var(--lyrics-glow-duration) forwards, lyrics-wobble var(--lyrics-wobble-duration) forwards',
);

root.style.setProperty('--lyrics-inactive-font-weight', '700');
root.style.setProperty('--lyrics-inactive-opacity', '0.33');
root.style.setProperty('--lyrics-inactive-scale', '0.95');
root.style.setProperty('--lyrics-inactive-offset', '0');

root.style.setProperty('--lyrics-active-font-weight', '700');
root.style.setProperty('--lyrics-active-opacity', '1');
root.style.setProperty('--lyrics-active-scale', '1');
root.style.setProperty('--lyrics-active-offset', '0');
break;
case 'scale':
root.style.setProperty('--lyrics-font-size', '1.4rem');
root.style.setProperty(
'--previous-lyrics',
'var(--ytmusic-text-primary)',
'--lyrics-line-height',
'var(--ytmusic-body-line-height)',
);
root.style.setProperty('--current-lyrics', 'var(--ytmusic-text-primary)');
root.style.setProperty('--size-lyrics', '1.2');
root.style.setProperty('--offset-lyrics', '0');
root.style.setProperty('--lyric-width', '83%');
root.style.setProperty('--lyrics-width', '83%');
root.style.setProperty('--lyrics-padding', '0');
root.style.setProperty('--lyrics-animations', 'none');

root.style.setProperty('--lyrics-inactive-font-weight', '400');
root.style.setProperty('--lyrics-inactive-opacity', '0.33');
root.style.setProperty('--lyrics-inactive-scale', '1');
root.style.setProperty('--lyrics-inactive-offset', '0');

root.style.setProperty('--lyrics-active-font-weight', '700');
root.style.setProperty('--lyrics-active-opacity', '1');
root.style.setProperty('--lyrics-active-scale', '1.2');
root.style.setProperty('--lyrics-active-offset', '0');
break;
case 'offset':
root.style.setProperty('--lyrics-font-size', '1.4rem');
root.style.setProperty(
'--previous-lyrics',
'var(--ytmusic-text-primary)',
'--lyrics-line-height',
'var(--ytmusic-body-line-height)',
);
root.style.setProperty('--current-lyrics', 'var(--ytmusic-text-primary)');
root.style.setProperty('--size-lyrics', '1');
root.style.setProperty('--offset-lyrics', '5%');
root.style.setProperty('--lyric-width', '100%');
root.style.setProperty('--lyrics-width', '100%');
root.style.setProperty('--lyrics-padding', '0');
root.style.setProperty('--lyrics-animations', 'none');

root.style.setProperty('--lyrics-inactive-font-weight', '400');
root.style.setProperty('--lyrics-inactive-opacity', '0.33');
root.style.setProperty('--lyrics-inactive-scale', '1');
root.style.setProperty('--lyrics-inactive-offset', '0');

root.style.setProperty('--lyrics-active-font-weight', '700');
root.style.setProperty('--lyrics-active-opacity', '1');
root.style.setProperty('--lyrics-active-scale', '1');
root.style.setProperty('--lyrics-active-offset', '5%');
break;
case 'focus':
root.style.setProperty('--lyrics-font-size', '1.4rem');
root.style.setProperty(
'--previous-lyrics',
'var(--ytmusic-text-secondary)',
'--lyrics-line-height',
'var(--ytmusic-body-line-height)',
);
root.style.setProperty('--current-lyrics', 'var(--ytmusic-text-primary)');
root.style.setProperty('--size-lyrics', '1');
root.style.setProperty('--offset-lyrics', '0');
root.style.setProperty('--lyric-width', '100%');
root.style.setProperty('--lyrics-width', '100%');
root.style.setProperty('--lyrics-padding', '0');
root.style.setProperty('--lyrics-animations', 'none');

root.style.setProperty('--lyrics-inactive-font-weight', '400');
root.style.setProperty('--lyrics-inactive-opacity', '0.33');
root.style.setProperty('--lyrics-inactive-scale', '1');
root.style.setProperty('--lyrics-inactive-offset', '0');

root.style.setProperty('--lyrics-active-font-weight', '700');
root.style.setProperty('--lyrics-active-opacity', '1');
root.style.setProperty('--lyrics-active-scale', '1');
root.style.setProperty('--lyrics-active-offset', '0');
break;
}
});
Expand Down
109 changes: 83 additions & 26 deletions src/plugins/synced-lyrics/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,40 @@
display: block !important;
}

/* :root {
--ytmusic-text-primary: #fff;
--ytmusic-text-secondary: #aaa;
} */

/* Variables are overridden by selected line effect */
:root {
/* Layout */
--global-margin: 0.7rem;
--previous-lyrics: var(--ytmusic-text-primary);
--current-lyrics: var(--ytmusic-text-primary);
--upcoming-lyrics: var(--ytmusic-text-secondary);
--size-lyrics: 1.2em;
--offset-lyrics: 1em;
--lyrics-padding: 0;

/* Typography */
--lyrics-font-family: Satoshi, Avenir, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell,
Open Sans, Helvetica Neue, sans-serif;
--lyrics-font-size: 1.4rem;
--lyrics-line-height: var(--ytmusic-body-line-height);
--lyrics-width: 100%;

/* Inactive Lyrics */
--lyrics-inactive-font-weight: 400;
--lyrics-inactive-opacity: 0.33;
--lyrics-inactive-scale: 1;
--lyrics-inactive-offset: 0;

/* Active Lyrics */
--lyrics-active-font-weight: 700;
--lyrics-active-opacity: 1;
--lyrics-active-scale: 1;
--lyrics-active-offset: 0;

/* Animations */
--lyrics-animations: lyrics-glow var(--lyrics-glow-duration) forwards, lyrics-wobble var(--lyrics-wobble-duration) forwards;
--lyrics-scale-duration: 0.166s;
--lyrics-opacity-transition: 0.33s;
--lyrics-glow-duration: var(--lyrics-duration, 2s);
--lyrics-wobble-duration: calc(var(--lyrics-duration, 2s) / 2);

/* Colors */
--glow-color: rgba(255, 255, 255, 0.5);
}

.lyric-container {
Expand All @@ -32,7 +54,7 @@
}

.synced-line {
width: var(--lyric-width, 100%);
width: var(--lyrics-width, 100%);

& > .text-lyrics {
cursor: pointer;
Expand All @@ -43,8 +65,7 @@
display: block;
justify-content: left;
text-align: left;
margin: 0.5rem 0;
margin-right: 20px;
margin: 0.5rem 20px 0.5rem 0;
transition: all 0.3s ease-in-out;
}

Expand All @@ -54,35 +75,46 @@
}

.text-lyrics {
font-family: var(--lyrics-font-family) !important;
font-size: var(--lyrics-font-size) !important;
font-weight: var(--lyrics-inactive-font-weight) !important;
line-height: var(--lyrics-line-height) !important;
padding-top: var(--lyrics-padding);
padding-bottom: var(--lyrics-padding);
scale: var(--lyrics-inactive-scale);
translate: var(--lyrics-inactive-offset);
transition:
scale var(--lyrics-scale-duration),
translate 0.3s ease-in-out;

display: block;
text-align: left;
margin: var(--global-margin) 0;
transition:
scale 0.3s ease-in-out,
translate 0.3s ease-in-out,
color 0.1s ease-in-out;
transform-origin: 0 50%;
}

.text-lyrics > span {
margin-inline: 0.1em;
display: inline-block;
white-space: pre-wrap;
opacity: var(--lyrics-inactive-opacity);
transition: opacity var(--lyrics-opacity-transition);
}

.previous > .text-lyrics {
color: var(--previous-lyrics);
font-weight: normal;
}

.current > .text-lyrics {
color: var(--current-lyrics);
font-weight: bold;
scale: var(--size-lyrics);
translate: var(--offset-lyrics) 0;
font-weight: var(--lyrics-active-font-weight) !important;
scale: var(--lyrics-active-scale);
translate: var(--lyrics-active-offset);
}

.current > .text-lyrics > span {
opacity: var(--lyrics-active-opacity);
animation: var(--lyrics-animations);
}

.upcoming > .text-lyrics {
color: var(--upcoming-lyrics);
font-weight: normal;
}

.lyrics-renderer {
Expand Down Expand Up @@ -162,3 +194,28 @@

transition: top 325ms ease-in-out;
}

/* Animations */
@keyframes lyrics-wobble {
from {
transform: translateY(0px);
}
33.33% {
transform: translateY(1.75px);
}
66.66% {
transform: translateY(-1.75px);
}
to {
transform: translateY(0px);
}
}

@keyframes lyrics-glow {
0% {
text-shadow: 0 0 1.5rem var(--glow-color);
}
to {
text-shadow: 0 0 0 var(--glow-color);
}
}
Loading
Loading