Add loading spinner to YouTube player windows
Song select: spinner shown via yt-loading class, removed when PLAYING. Game page: spinner shown via :empty pseudo-class while iframe loads. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>main
parent
808da507f6
commit
9bc7a57d69
|
|
@ -77,6 +77,27 @@
|
|||
border: 0;
|
||||
}
|
||||
|
||||
.song-select-screen__yt-preview.yt-loading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.song-select-screen__yt-preview.yt-loading::after {
|
||||
content: '';
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border: 3px solid rgba(217, 70, 239, 0.2);
|
||||
border-top-color: #d946ef;
|
||||
border-radius: 50%;
|
||||
animation: yt-spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes yt-spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.song-select-screen__content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
|
|
|||
|
|
@ -72,8 +72,9 @@ function startYouTubePreview(song: Song, host: HTMLElement): () => void {
|
|||
let player: YT.Player | null = null
|
||||
let fadeIv = 0
|
||||
|
||||
// Clear any previous player content
|
||||
// Clear any previous player content and show spinner
|
||||
host.innerHTML = ''
|
||||
host.classList.add('yt-loading')
|
||||
|
||||
const timer = window.setTimeout(() => {
|
||||
loadYouTubeApi().then(() => {
|
||||
|
|
@ -109,6 +110,7 @@ function startYouTubePreview(song: Song, host: HTMLElement): () => void {
|
|||
onStateChange(e: YT.OnStateChangeEvent) {
|
||||
if (destroyed || !player) return
|
||||
if (e.data === YT.PlayerState.PLAYING) {
|
||||
host.classList.remove('yt-loading')
|
||||
const maxVol = MAX_VOLUME * 100
|
||||
const step = (maxVol * FADE_STEP_MS) / FADE_IN_MS
|
||||
fadeIv = window.setInterval(() => {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,27 @@
|
|||
border: 0;
|
||||
}
|
||||
|
||||
.ytPlayer:empty {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.ytPlayer:empty::after {
|
||||
content: '';
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border: 3px solid rgba(217, 70, 239, 0.2);
|
||||
border-top-color: #d946ef;
|
||||
border-radius: 50%;
|
||||
animation: yt-spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes yt-spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.loadingOverlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue