From 1c3ddbd907fd22d91a310f3e5041b15231b35a42 Mon Sep 17 00:00:00 2001 From: nutty Date: Thu, 23 Jul 2026 15:15:44 +1000 Subject: [PATCH] Added auto scroll when text is too long --- now-playing/script.js | 74 +++++++++++++---- now-playing/style.css | 111 ++++++++++++++++++++++++- now-playing/themes/card/script.js | 4 +- now-playing/themes/card/style.css | 18 ++-- now-playing/themes/classic/script.js | 4 +- now-playing/themes/classic/style.css | 4 +- now-playing/themes/compact/script.js | 98 +++++++++++++++------- now-playing/themes/compact/style.css | 52 ++++++++---- now-playing/themes/simple/index.html | 27 +++--- now-playing/themes/simple/script.js | 52 ++++++++++-- now-playing/themes/simple/style.css | 61 +++++++------- now-playing/themes/standard/index.html | 3 - now-playing/themes/standard/script.js | 11 ++- now-playing/themes/standard/style.css | 18 +--- 14 files changed, 389 insertions(+), 148 deletions(-) diff --git a/now-playing/script.js b/now-playing/script.js index 2fee884..37c13e4 100644 --- a/now-playing/script.js +++ b/now-playing/script.js @@ -11,6 +11,7 @@ const urlParams = new URLSearchParams(queryString); const REQUIRED_VERSION = '0.0.2'; const SMTC_BRIDGE_DOWNLOAD_URL = 'https://github.com/nuttylmao/smtc-bridge/releases'; +let VersionChecked = false; /////////////////// // PAGE ELEMENTS // @@ -70,21 +71,6 @@ else // Set text alignment document.documentElement.style.setProperty('--text-alignment', `${textAlignment}`); -switch (textAlignment) -{ - case 'left': - document.documentElement.style.setProperty('--justify-content', `flex-start`); - document.documentElement.style.setProperty('--trailing-fade', `linear-gradient(to right, black calc(100% - 1em), transparent 100%)`); - break; - case 'center': - document.documentElement.style.setProperty('--justify-content', `center`); - document.documentElement.style.setProperty('--trailing-fade', `linear-gradient(to right, black calc(100% - 1em), transparent 100%)`); - break; - case 'right': - document.documentElement.style.setProperty('--justify-content', `flex-end`); - document.documentElement.style.setProperty('--trailing-fade', ``); - break; -} @@ -167,7 +153,10 @@ async function FetchMedia() { } // Check the SMTC Bridge version - CheckSMTCBridgeVersion(data.app_version); + if (!VersionChecked) { + CheckSMTCBridgeVersion(data.app_version); + VersionChecked = true; + } // Update the UI with the received data // console.log(data); @@ -410,4 +399,57 @@ function SetVisibility(visible) { } else { mainWrapper.style.animation = `${hideAnimation} 0.5s ease-out forwards`; } +} + +// MARQUEE LOGIC +// This is a more advanced marquee implementation that calculates the overflow distance and adjusts the scroll speed accordingly +const labelData = new Map(); + +// Adjust this value to change scroll speed (pixels per second) +const SCROLL_SPEED_PX_PER_SEC = 40; + +function SetLabelText(elementId, text) { + const label = document.getElementById(elementId); + if (!label) return; + + labelData.set(elementId, text); + ApplyMarquee(label, text); + + // Keep it responsive on container resize + if (!label._resizeObserver) { + label._resizeObserver = new ResizeObserver(() => { + const currentText = labelData.get(elementId); + if (currentText) ApplyMarquee(label, currentText); + }); + label._resizeObserver.observe(label); + } +} + +function ApplyMarquee(label, text) { + // 1. Render single span to measure dimensions + label.classList.remove('is-overflowing'); + label.innerHTML = `${text}`; + + const scrollContent = label.querySelector('.scroll-content'); + + const textWidth = scrollContent.scrollWidth; + const containerWidth = label.clientWidth; + const overflowDistance = textWidth - containerWidth; + + // 2. Check if text exceeds container + if (overflowDistance > 0) { + // Calculate travel distance in percentage relative to scrollContent's width + const distancePercent = (overflowDistance / textWidth) * 100; + + // Compute duration to keep speed consistent regardless of length + // We multiply travel time by 2 (for both directions) plus 3 seconds for pauses + const travelTime = overflowDistance / SCROLL_SPEED_PX_PER_SEC; + const totalDuration = (travelTime * 2) + 3; + + // Pass calculated variables to CSS + scrollContent.style.setProperty('--scroll-distance', `-${distancePercent}%`); + label.style.setProperty('--marquee-duration', `${totalDuration}s`); + + label.classList.add('is-overflowing'); + } } \ No newline at end of file diff --git a/now-playing/style.css b/now-playing/style.css index 49bd6c0..84985a0 100644 --- a/now-playing/style.css +++ b/now-playing/style.css @@ -10,7 +10,8 @@ body { justify-content: center; align-items: center; height: 100vh; - margin: 0.5em; + padding: 0.5em; + box-sizing: border-box; } @@ -140,4 +141,112 @@ body { transform: translateX(1em); opacity: 0; } +} + + + +@property --mask-left { + syntax: ''; + inherits: false; + initial-value: black; +} + +@property --mask-right { + syntax: ''; + inherits: false; + initial-value: transparent; +} + +.text-label { + --fade-width: 0.5em; + white-space: nowrap; + overflow: hidden; + display: block; + width: 100%; + mask-image: var(--trailing-fade); + -webkit-mask-image: var(--trailing-fade); + transition: opacity 0.25s ease-in-out; +} + +.text-label:empty { + display: none !important; +} + +.text-label:has(.scroll-content:empty), +.text-label:has(#track-label:empty) { + display: none !important; +} + +.text-label .scroll-content { + display: inline-flex; + white-space: nowrap; + will-change: transform; +} + +.text-label.is-overflowing .scroll-content { + animation: ping-pong-scroll var(--marquee-duration, 8s) linear infinite; +} + +.text-label.is-overflowing { + animation: ping-pong-mask var(--marquee-duration, 8s) linear infinite; + + /* Static gradient structure referencing dynamic color variables */ + mask-image: linear-gradient( + to right, + var(--mask-left) 0px, + black var(--fade-width), + black calc(100% - var(--fade-width)), + var(--mask-right) 100% + ); + -webkit-mask-image: linear-gradient( + to right, + var(--mask-left) 0px, + black var(--fade-width), + black calc(100% - var(--fade-width)), + var(--mask-right) 100% + ); +} + +@keyframes ping-pong-scroll { + 0%, 15% { + transform: translateX(0%); + } + 50%, 65% { + transform: translateX(var(--scroll-distance, -100%)); + } + 100% { + transform: translateX(0%); + } +} + +@keyframes ping-pong-mask { + /* 1. AT START: Left is solid (black), Right is faded (transparent) */ + 0%, 15% { + --mask-left: black; + --mask-right: transparent; + } + + /* 2. MOVING LEFT: Left smoothly fades in (transparent), Right stays faded */ + 22%, 43% { + --mask-left: transparent; + --mask-right: transparent; + } + + /* 3. AT FAR END: Right smoothly solidifies (black), Left stays faded */ + 50%, 65% { + --mask-left: transparent; + --mask-right: black; + } + + /* 4. MOVING RIGHT: Right smoothly fades back out (transparent) */ + 72%, 93% { + --mask-left: transparent; + --mask-right: transparent; + } + + /* 5. RETURN TO START: Left smoothly solidifies (black) */ + 100% { + --mask-left: black; + --mask-right: transparent; + } } \ No newline at end of file diff --git a/now-playing/themes/card/script.js b/now-playing/themes/card/script.js index 623effe..caa9b35 100644 --- a/now-playing/themes/card/script.js +++ b/now-playing/themes/card/script.js @@ -53,8 +53,8 @@ async function ChangeTrack(mediaProps, accentColorPalette) { // Wait for fade (0.5s), then swap the real text and hide overlay setTimeout(() => { - trackLabel.innerText = swapArtistTrack ? mediaProps.Artist : mediaProps.Title; - artistLabel.innerText = swapArtistTrack ? mediaProps.Title : mediaProps.Artist; + SetLabelText('track-label', swapArtistTrack ? mediaProps.Artist : mediaProps.Title); + SetLabelText('artist-label', swapArtistTrack ? mediaProps.Title : mediaProps.Artist); // Extract the image source string (use fallback if Windows has no art) const newArtUrl = mediaProps.Thumbnail ?? './images/placeholder.png'; diff --git a/now-playing/themes/card/style.css b/now-playing/themes/card/style.css index b7f33ad..c578d13 100644 --- a/now-playing/themes/card/style.css +++ b/now-playing/themes/card/style.css @@ -7,13 +7,12 @@ width: 500px; display: flex; flex-direction: row; - align-items: stretch; + align-items: stretch; gap: 0.5em; opacity: 0; } #album-art-container { - /* 1. Tell it to maintain a 1:1 square ratio */ aspect-ratio: 1 / 1; overflow: hidden; border-radius: var(--component-radius); @@ -85,11 +84,12 @@ #song-info-wrapper { position: relative; /* Keeps it in the document flow */ z-index: 2; /* Sits above the background-layer */ - + padding: 10% 7.5%; display: flex; flex-direction: column; gap: 0.3em; + max-height: 100%; } #track-label { @@ -134,9 +134,9 @@ border-radius: 10000px; background-color: var(--accent-color, #ffffff); transition: width 1s ease-in-out, background-color 1s ease-in-out; - + /* This makes the handle track the end of the bar */ - position: relative; + position: relative; } #progress-bar-fill::after { @@ -145,16 +145,16 @@ right: -6px; /* Adjust to center the circle on the end of the bar */ top: 50%; transform: translateY(-50%); - + width: 0.8em; /* Diameter of your circle */ height: 0.8em; background-color: var(--accent-color, #ffffff); border-radius: 50%; - filter: brightness(1.4); + filter: brightness(1.4); box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); /* Adds depth */ - + /* Optional: Hide it if the width is too small */ - opacity: 0; + opacity: 0; transition: all 1s ease-in-out; } diff --git a/now-playing/themes/classic/script.js b/now-playing/themes/classic/script.js index 122a5be..0789624 100644 --- a/now-playing/themes/classic/script.js +++ b/now-playing/themes/classic/script.js @@ -53,8 +53,8 @@ async function ChangeTrack(mediaProps, accentColorPalette) { // Wait for fade (0.5s), then swap the real text and hide overlay setTimeout(async () => { - trackLabel.innerText = swapArtistTrack ? mediaProps.Artist : mediaProps.Title; - artistLabel.innerText = swapArtistTrack ? mediaProps.Title : mediaProps.Artist; + SetLabelText('track-label', swapArtistTrack ? mediaProps.Artist : mediaProps.Title); + SetLabelText('artist-label', swapArtistTrack ? mediaProps.Title : mediaProps.Artist); // Extract the image source string (use fallback if Windows has no art) const newArtUrl = mediaProps.Thumbnail ?? './images/placeholder.png'; diff --git a/now-playing/themes/classic/style.css b/now-playing/themes/classic/style.css index a0f2969..1223703 100644 --- a/now-playing/themes/classic/style.css +++ b/now-playing/themes/classic/style.css @@ -64,7 +64,7 @@ flex-direction: row; align-items: center; overflow: hidden; - gap: 0.5em; + gap: 1em; transition: all 0.25s ease-in-out; } @@ -99,7 +99,7 @@ position: relative; /* Keeps it in the document flow */ z-index: 2; /* Sits above the background-layer */ - padding: 1em 1.75em; + padding: 1em 1.3em; display: flex; flex-direction: column; gap: 0.3em; diff --git a/now-playing/themes/compact/script.js b/now-playing/themes/compact/script.js index 6557235..bdc23b5 100644 --- a/now-playing/themes/compact/script.js +++ b/now-playing/themes/compact/script.js @@ -48,23 +48,28 @@ async function ChangeTrack(mediaProps, accentColorPalette) { // Wait for fade (0.5s), then swap the real text and hide overlay setTimeout(() => { - trackLabel.innerText = swapArtistTrack ? mediaProps.Artist : mediaProps.Title; - artistLabel.innerText = swapArtistTrack ? mediaProps.Title : mediaProps.Artist; - trackLabelBackground.innerText = swapArtistTrack ? mediaProps.Artist : mediaProps.Title; - artistLabelBackground.innerText = swapArtistTrack ? mediaProps.Title : mediaProps.Artist; + // trackLabel.innerText = swapArtistTrack ? mediaProps.Artist : mediaProps.Title; + // artistLabel.innerText = swapArtistTrack ? mediaProps.Title : mediaProps.Artist; + // trackLabelBackground.innerText = swapArtistTrack ? mediaProps.Artist : mediaProps.Title; + // artistLabelBackground.innerText = swapArtistTrack ? mediaProps.Title : mediaProps.Artist; + if (swapArtistTrack) { + SetSongInfo(mediaProps.Artist, mediaProps.Title); + } else { + SetSongInfo(mediaProps.Title, mediaProps.Artist); + } // Extract the image source string (use fallback if Windows has no art) // Set the pill color switch (themeVariant) { case "compact-inverted": - songInfoContainer.style.backgroundColor = accentColorPalette.LightVibrant; + progressBarTrack.style.backgroundColor = accentColorPalette.LightVibrant; progressBar.style.background = `color-mix(in srgb, ${accentColorPalette.DarkMuted}, black 60%)`; songLabel.style.color = accentColorPalette.LightVibrant; songLabelBackground.style.color = accentColorPalette.DarkVibrant; break; default: - songInfoContainer.style.backgroundColor = `color-mix(in srgb, ${accentColorPalette.DarkMuted}, black 60%)`; + progressBarTrack.style.backgroundColor = `color-mix(in srgb, ${accentColorPalette.DarkMuted}, black 60%)`; progressBar.style.background = accentColorPalette.LightVibrant; songLabel.style.color = accentColorPalette.DarkVibrant; songLabelBackground.style.color = accentColorPalette.LightVibrant; @@ -74,30 +79,6 @@ async function ChangeTrack(mediaProps, accentColorPalette) { songLabel.style.opacity = ""; songLabelBackground.style.opacity = ""; - // // If text is too long, add a marquee - // requestAnimationFrame(() => { - // const containerWidth = songInfoContainer.clientWidth; - // const textWidth = trackLabel.clientWidth + artistLabel.clientWidth; - - - // console.log(containerWidth); - // console.log(textWidth); - - // if (textWidth > containerWidth) { - // songLabel.classList.add('scrolling-text'); - // songLabelBackground.classList.add('scrolling-text'); - // // Calculate speed: 50 pixels per second is a good standard - // const duration = (textWidth + containerWidth) / 50; - // console.log(duration); - // document.documentElement.style.setProperty('--scroll-duration', `${duration}s`); - // document.documentElement.style.setProperty('--container-width', `${textWidth}px`); - // document.documentElement.style.setProperty('--text-width', `-${textWidth}px`); - // } else { - // songLabel.classList.remove('scrolling-text'); - // songLabelBackground.classList.remove('scrolling-text'); - // } - // }); - setTimeout(() => { SetVisibility(true); // Show the overlay for a few seconds if autoHide is enabled }, 250); @@ -127,7 +108,62 @@ function SetProgressInfo(timelineProps, currentPositionMs, accentColorPalette) { // Update the clip-path progressBar.style.clipPath = `inset(0 ${clipRight}% 0 0)`; + progressBarTrack.style.clipPath = `inset(0 0 0 ${progressPercent}%)`; + // // Set the progress bar but with a transition for smoothness // const clipRight = progressPercent; - // progressBar.style.maskImage = `linear-gradient(to right, black calc(${clipRight}% - 4em), transparent ${clipRight}%)` + // const transitionWidth = '1em'; + // progressBar.style.maskImage = `linear-gradient(to right, black calc(${clipRight}% - ${transitionWidth}), transparent ${clipRight}%)` + // progressBarTrack.style.maskImage = `linear-gradient(to right, transparent calc(${clipRight}% - ${transitionWidth}), black ${clipRight}%)`; +} + +// MARQUEE LOGIC +// This is a more advanced marquee implementation that calculates the overflow distance and adjusts the scroll speed accordingly + +// Call this function whenever the track changes +function SetSongInfo(trackName, artistName) { + // Update main text and background layer simultaneously + UpdateSingleSongLabel('song-label', trackName, artistName); + UpdateSingleSongLabel('song-label-background', trackName, artistName); +} + +function UpdateSingleSongLabel(containerId, trackName, artistName) { + const container = document.getElementById(containerId); + if (!container) return; + + // 1. Structure the inner HTML with a wrapper so we can measure exact inline width + container.classList.remove('is-overflowing'); + container.innerHTML = ` + + ${trackName} + ${artistName} + + `; + + const scrollContent = container.querySelector('.scroll-content'); + + // 2. Measure total width of (Track + Artist) against parent width + const textWidth = scrollContent.scrollWidth; + const containerWidth = container.clientWidth; + const overflowDistance = textWidth - containerWidth; + + // 3. If the combined row overflows, set the CSS variables and add class + if (overflowDistance > 0) { + const distancePercent = (overflowDistance / textWidth) * 100; + const travelTime = overflowDistance / SCROLL_SPEED_PX_PER_SEC; + const totalDuration = (travelTime * 2) + 3; // 3 seconds total for start/end pauses + + scrollContent.style.setProperty('--scroll-distance', `-${distancePercent}%`); + container.style.setProperty('--marquee-duration', `${totalDuration}s`); + + container.classList.add('is-overflowing'); + } + + // 4. Attach ResizeObserver once to handle responsive window resizes + if (!container._resizeObserver) { + container._resizeObserver = new ResizeObserver(() => { + UpdateSingleSongLabel(containerId, trackName, artistName); + }); + container._resizeObserver.observe(container); + } } \ No newline at end of file diff --git a/now-playing/themes/compact/style.css b/now-playing/themes/compact/style.css index d1413ac..5c20623 100644 --- a/now-playing/themes/compact/style.css +++ b/now-playing/themes/compact/style.css @@ -35,6 +35,10 @@ -webkit-mask-image: linear-gradient(to right, black calc(100% - 4em), transparent 100%); */ } +#progress-bar-track { + transition: all 1s ease-in-out; +} + .progress { box-sizing: border-box; padding: 0.25em 0.75em; @@ -53,7 +57,7 @@ gap: 0.5em; min-width: 100%; justify-content: var(--justify-content); - overflow: visible; + overflow: hidden; } #artist-label, @@ -69,23 +73,39 @@ } .text-label { - white-space: nowrap; - /* overflow: hidden; */ transition: opacity 0.25s ease-in-out; } - -/* TODO: Marquee doesn't work that well, disabling for now */ -/* .scrolling-text { - animation: marquee var(--scroll-duration, 15s) linear infinite; - display: inline-block; +/* Inner wrapper holding track + artist inline */ +#song-label .scroll-content, +#song-label-background .scroll-content { + display: inline-flex; + flex-direction: row; + align-items: baseline; + gap: 0.5em; /* Spacing between Track and Artist */ + white-space: nowrap; + will-change: transform; } -@keyframes marquee { - 0% { - transform: translateX(var(--container-width)); - } - 100% { - transform: translateX(var(--text-width)); - } -} */ \ No newline at end of file +/* Preserve original font weights */ +.track-label { + font-weight: 700; +} + +.artist-label { + font-size: 0.8em; + font-weight: 400; + opacity: 0.7; +} + +/* Marquee scroll animation */ +#song-label.is-overflowing .scroll-content, +#song-label-background.is-overflowing .scroll-content { + animation: ping-pong-scroll var(--marquee-duration, 8s) linear infinite; +} + +/* Mask animation applied to container */ +#song-label.is-overflowing, +#song-label-background.is-overflowing { + animation: ping-pong-mask var(--marquee-duration, 8s) linear infinite; +} \ No newline at end of file diff --git a/now-playing/themes/simple/index.html b/now-playing/themes/simple/index.html index 9519a12..5c200da 100644 --- a/now-playing/themes/simple/index.html +++ b/now-playing/themes/simple/index.html @@ -1,20 +1,19 @@
-
-
-
-
-
+
+
+
+
-
-
 
-
 
-
- +
+
 
+
 
+
+
0:00
+
+
+
+
0:00
\ No newline at end of file diff --git a/now-playing/themes/simple/script.js b/now-playing/themes/simple/script.js index 0549f9f..ad6e24d 100644 --- a/now-playing/themes/simple/script.js +++ b/now-playing/themes/simple/script.js @@ -10,6 +10,7 @@ const albumArtTransition = document.getElementById('album-art-transition-layer') const trackLabel = document.getElementById('track-label'); const artistLabel = document.getElementById('artist-label'); const progressContainer = document.getElementById('progress-container'); +const progressBarFill = document.getElementById('progress-bar-fill'); const currentTimeLabel = document.getElementById('current-time'); const durationLabel = document.getElementById('duration'); @@ -34,8 +35,9 @@ if (!showProgressBar) progressContainer.style.display = 'none'; // If text alignment is 'right', swap the album art to the right hand side too -if (textAlignment == 'right') - document.getElementById('yet-another-wrapper-yup').appendChild(document.getElementById('album-art-container')); +if (textAlignment == 'right') { + mainWrapper.style.flexDirection = 'row-reverse'; +} @@ -52,8 +54,10 @@ async function ChangeTrack(mediaProps) { // Wait for fade (0.5s), then swap the real text and hide overlay setTimeout(() => { - trackLabel.innerText = swapArtistTrack ? mediaProps.Artist : mediaProps.Title; - artistLabel.innerText = swapArtistTrack ? mediaProps.Title : mediaProps.Artist; + // trackLabel.innerText = swapArtistTrack ? mediaProps.Artist : mediaProps.Title; + // artistLabel.innerText = swapArtistTrack ? mediaProps.Title : mediaProps.Artist; + SetLabelText('track-label', swapArtistTrack ? mediaProps.Artist : mediaProps.Title); + SetLabelText('artist-label', swapArtistTrack ? mediaProps.Title : mediaProps.Artist); // Extract the image source string (use fallback if Windows has no art) const newArtUrl = mediaProps.Thumbnail ?? './images/placeholder.png'; @@ -81,4 +85,42 @@ function SetProgressInfo(timelineProps, currentPositionMs, accentColorPalette) { durationLabel.innerText = ConvertMillisecondsToHoursMinutesSecondsSoItLooksBetterAndNotCringe(timelineProps.EndTime); -} \ No newline at end of file + + // Set progressbar + // Ensure we don't divide by zero or exceed 100% + const durationMs = timelineProps.EndTime; + let progressPercent = durationMs > 0 ? (currentPositionMs / durationMs) * 100 : 0; + progressPercent = Math.min(100, Math.max(0, progressPercent)); + progressBarFill.style.width = `${progressPercent}%`; + progressBarFill.style.setProperty('--accent-color', accentColorPalette.LightVibrant); + switch (themeVariant) { + case "matte": + progressBarFill.style.setProperty('--accent-color', accentColorPalette.DarkVibrant); + break; + case "matte-dark": + default: + progressBarFill.style.setProperty('--accent-color', accentColorPalette.LightVibrant); + break; + } +} + + +// Helper function to calculate height of album art +const observer = new ResizeObserver(entries => { + for (let entry of entries) { + // Get the accurate rendered height of song-info-container + const infoHeight = entry.contentRect.height; + + // Calculate 125% of that height + const targetSize = infoHeight * 1.5; + + console.log(targetSize); + + // Apply to album art (setting both width & height ensures it stays square) + albumArtContainer.style.height = `${targetSize}px`; + albumArtContainer.style.width = `${targetSize}px`; + } +}); + +// Start watching the song info container for size changes +observer.observe(songInfoContainer); \ No newline at end of file diff --git a/now-playing/themes/simple/style.css b/now-playing/themes/simple/style.css index d65e88d..5e0ae26 100644 --- a/now-playing/themes/simple/style.css +++ b/now-playing/themes/simple/style.css @@ -6,23 +6,13 @@ width: 500px; display: flex; flex-direction: row; - align-items: stretch; - opacity: 0; -} - -#yet-another-wrapper-yup { - position: relative; - flex: 1; - display: flex; - flex-direction: row; align-items: center; - gap: 0.75em; - transition: all 0.25s ease-in-out; + gap: 1em; + opacity: 0; } #album-art-container { /* 1. Tell it to maintain a 1:1 square ratio */ - height: 150%; aspect-ratio: 1 / 1; overflow: hidden; border-radius: var(--border-radius); @@ -62,23 +52,13 @@ overflow: hidden; flex-grow: 1; min-width: 0; + gap: 0.25em; } #background-transition-layer { z-index: 0; } -/* The content sits on top */ -#song-info-wrapper { - position: relative; /* Keeps it in the document flow */ - z-index: 2; /* Sits above the background-layer */ - - padding: 1em 1.75em; - display: flex; - flex-direction: column; - gap: 0.3em; -} - #track-label { font-size: 1em; font-weight: 600; @@ -93,11 +73,36 @@ } #progress-container { - font-size: 0.6em; - font-weight: 400; - opacity: 0.6; - text-align: var(--text-alignment); - margin-top: 0.5em; + display: flex; + flex-direction: row; + align-items: center; + gap: 0.2em; + margin-top: 0.2em; + gap: 0.5em; +} + +#progress-bar-track { + width: 100%; + height: 0.4em; + border-radius: 1em; + background-color: #ffffff3a; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); /* Adds depth */ +} + +#progress-bar-fill { + height: 100%; + width: 0%; /* JS will control this */ + border-radius: 1em; + background-color: var(--accent-color, #ffffff); + transition: width 1s ease-in-out, background-color 1s ease-in-out; + + /* This makes the handle track the end of the bar */ + position: relative; +} + +.progress-text { + font-size: 0.7em; + opacity: 0.5; } .text-label { diff --git a/now-playing/themes/standard/index.html b/now-playing/themes/standard/index.html index 3ec4a50..bd9b89c 100644 --- a/now-playing/themes/standard/index.html +++ b/now-playing/themes/standard/index.html @@ -20,9 +20,6 @@
0:00
- -
-
diff --git a/now-playing/themes/standard/script.js b/now-playing/themes/standard/script.js index a64e000..fa6006c 100644 --- a/now-playing/themes/standard/script.js +++ b/now-playing/themes/standard/script.js @@ -5,6 +5,7 @@ const mainWrapper = document.getElementById('main-wrapper'); const albumArtContainer = document.getElementById('album-art-container'); const songInfoContainer = document.getElementById('song-info-container'); +const songInfoWrapper = document.getElementById('song-info-wrapper'); const albumArtLayer = document.getElementById('album-art-layer'); const albumArtTransition = document.getElementById('album-art-transition-layer'); const backgroundLayer = document.getElementById('background-layer'); @@ -48,6 +49,10 @@ switch (themeVariant) { break; } +// If text alignment is 'right', swap the album art to the right hand side too +if (textAlignment == 'right') { + songInfoContainer.style.flexDirection = 'row-reverse'; +} //////////////////// @@ -65,8 +70,8 @@ async function ChangeTrack(mediaProps, accentColorPalette) { // Wait for fade (0.5s), then swap the real text and hide overlay setTimeout(async () => { - trackLabel.innerText = swapArtistTrack ? mediaProps.Artist : mediaProps.Title; - artistLabel.innerText = swapArtistTrack ? mediaProps.Title : mediaProps.Artist; + SetLabelText('track-label', swapArtistTrack ? mediaProps.Artist : mediaProps.Title); + SetLabelText('artist-label', swapArtistTrack ? mediaProps.Title : mediaProps.Artist); switch (themeVariant) { case "matte": @@ -100,6 +105,8 @@ async function ChangeTrack(mediaProps, accentColorPalette) { backgroundLayer.style.opacity = ""; albumArtLayer.style.opacity = ""; + console.log(songInfoWrapper.clientWidth); + setTimeout(() => { // Set the image backgroundTransitionLayer.style.backgroundImage = `url('${newArtUrl}')`; diff --git a/now-playing/themes/standard/style.css b/now-playing/themes/standard/style.css index 7b00cdd..90959e8 100644 --- a/now-playing/themes/standard/style.css +++ b/now-playing/themes/standard/style.css @@ -7,7 +7,7 @@ width: 500px; display: flex; flex-direction: row; - align-items: stretch; + align-items: stretch; gap: 0.5em; opacity: 0; } @@ -115,14 +115,6 @@ text-align: var(--text-alignment); } -.text-label { - white-space: nowrap; - overflow: hidden; - mask-image: var(--trailing-fade); - -webkit-mask-image: var(--trailing-fade); - transition: opacity 0.25s ease-in-out; -} - #progress-container { display: flex; flex-direction: row; @@ -151,14 +143,6 @@ position: relative; } -/* #time-container { - display: flex; - justify-content: space-between; - font-size: 0.7em; - opacity: 0.5; - display: none; -} */ - .progress-text { font-size: 0.7em; opacity: 0.5;