hw-gs-player

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 98985aebfdf5f33de226c9d219e92eb764fc176e
parent a52a220c5f60cfb008ffa15df4fb1c5fc6f221ae
Author: Sunny <122193933+Sunny-JP@users.noreply.github.com>
Date:   Thu, 20 Mar 2025 22:12:36 +0900

adjust player style (#18)


Diffstat:
Msrc/components/Player.vue | 364+++++--------------------------------------------------------------------------
Asrc/player-style.css | 261+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/style.css | 4+++-
3 files changed, 283 insertions(+), 346 deletions(-)

diff --git a/src/components/Player.vue b/src/components/Player.vue @@ -1,9 +1,9 @@ <script setup lang="ts"> import { YoutubeIframe } from '@vue-youtube/component'; -import { ref, computed, onUnmounted, nextTick, watch } from 'vue'; +import { ref, computed, onUnmounted, watch } from 'vue'; import queue from '../queue'; import SvgIcon from '@jamescoyle/vue-icon'; -import { mdiRepeatOnce, mdiRepeatOff } from '@mdi/js'; +import { mdiRepeatOnce, mdiRepeatOff, mdiStarCheck, mdiStarPlusOutline } from '@mdi/js'; // YouTube player instance const player = ref<any>(null); @@ -21,15 +21,6 @@ const titleName = ref(); // Album info let albumTitle = queue.get_albumTitle(); -// Title scrolling -const titleElement = ref<HTMLElement | null>(null); -const needsScroll = ref(false); -const parentWidth = ref(0); -const textWidth = ref(0); -const isAnimating = ref(false); -const SCROLL_SPEED = 40; // px/s -const WAIT_TIME = 2000; // ms - // Fullscreen mode const isFullscreen = ref(false); const animationClass = ref(""); @@ -61,49 +52,27 @@ const onReady = (event: { target: any }) => { endTime.value = Math.floor(event.target.getDuration()); title.value = event.target.getVideoData(); titleName.value = title.value['title']; - - nextTick(() => { - if (titleElement.value) { - parentWidth.value = titleElement.value.parentElement?.offsetWidth || 0; - textWidth.value = titleElement.value.scrollWidth; - needsScroll.value = textWidth.value > parentWidth.value; - - if (needsScroll.value) { - startScrolling(); - } - } - }); -}; - -// Compute animation duration -const animationDuration = computed(() => { - return needsScroll.value ? textWidth.value / SCROLL_SPEED : 0; -}); - -// Start scrolling if needed -const startScrolling = async () => { - if (!needsScroll.value) return; - await new Promise(resolve => setTimeout(resolve, WAIT_TIME)); - isAnimating.value = true; }; // Handle video state changes const onStateChange = (event: { target: any; data: number }) => { + if (intervalId.value !== null) { + clearInterval(intervalId.value); + intervalId.value = null; + } + if (event.data === 1) { // Playing isPlaying.value = true; intervalId.value = window.setInterval(() => { nowTime.value = Math.floor(event.target.getCurrentTime()); - }, 250); + }, 200); } else if (event.data === 0) { // End isPlaying.value = false; queue.get_next(); } else if (event.data === 2) { // Paused isPlaying.value = false; - if (intervalId.value !== null) { - clearInterval(intervalId.value); - intervalId.value = null; - } } + albumTitle = queue.get_albumTitle(); }; @@ -154,19 +123,7 @@ const renderKey = queue.get_playerRenderKey(); <div class="info_box"> <!-- Video title --> <div class="title" @click="toggleFullscreen"> - <div - ref="titleElement" - class="scroll-container" - :class="{ scrolling: isAnimating }" - :style="isAnimating ? `--animation-duration: ${animationDuration}s;` : ''" - > - <span v-if="needsScroll" class="scroll-text"> - {{ titleName }}&nbsp;&nbsp;&nbsp;{{ titleName }} - </span> - <span v-else class="single-text"> - {{ titleName }} - </span> - </div> + {{ titleName }} </div> <!-- Time and album info --> @@ -181,6 +138,9 @@ const renderKey = queue.get_playerRenderKey(); <div class="fs_loop" @click="queue.onLoopButton()"> <SvgIcon type="mdi" :path="queue.isLoop.value ? mdiRepeatOnce : mdiRepeatOff" /> </div> + <div class="fs_fav" @click="queue.onLoopButton()"> + <SvgIcon type="mdi" :path="queue.isLoop.value ? mdiStarCheck : mdiStarPlusOutline" /> + </div> </div> <div class="fs_time_container"> @@ -197,299 +157,13 @@ const renderKey = queue.get_playerRenderKey(); </div> </button> </div> -</template> + <!-- song list + <div class="song_list"> + </div> + --> +</template> <style scoped> -/* overall frame */ -.container { - position: fixed; - bottom: 0; - width: 100%; - height: 10vw; - max-height: 60px; - background: #000000; - border-top: #404040 solid 2px; - display: flex; - align-items: center; - justify-content: center; - padding-top: clamp(1px, 2vw, 10px); - padding-bottom: clamp(1px, 2vw, 10px); - flex-direction: row; -} - -.fscontainer { - display: flex; - flex-direction: column; - align-items: center; - padding: 30px; - background: #000000; -} - -.slide-down { - animation: slideDown 0.25s ease forwards; -} - -.slide-up { - animation: slideUp 0.25s ease forwards; -} - -@keyframes slideDown { - 0% { - transform: translateY(-100px); - opacity: 0; - } - 100% { - transform: translateY(0); - } - 40%,100% { - opacity: 1; - } -} - -@keyframes slideUp { - 0% { - transform: translateY(100px); - opacity: 0; - } - 100% { - transform: translateY(0); - } - 40%,100% { - opacity: 1; - } -} - -/* title, album, time */ -.container .info_box { - margin-left: 10px; - padding: 0px 10px 0px 0px; - width: 70vw; - max-width: 300px; - color: white; -} - -.fscontainer .info_box { - position: relative; - top: 10px; - margin: 5px; - width: 100%; - max-width: 500px; -} - -.title { - cursor: pointer; - overflow: hidden; - white-space: nowrap; - position: relative; - width: 100%; -} - -.container .scroll-container { - display: flex; - align-items: center; - white-space: nowrap; - font-size: clamp(2px, calc(4vw - 1.3px), 20px); -} - -.fscontainer .scroll-container { - display: flex; - align-items: center; - white-space: nowrap; - font-size: clamp(3px, calc(6vw - 2px), 30px); -} - -.scrolling .scroll-text { - display: inline-block; - animation: scrollText var(--animation-duration) linear infinite; -} - -@keyframes scrollText { - 0% { - transform: translateX(0); - } - - 20% { - transform: translateX(0); - } - - 97% { - opacity: 1; - } - - 98% { - opacity: 0; - transform: translateX(calc(-50%)); - } - - 99% { - opacity: 0; - transform: translateX(0); - } - - 100% { - opacity: 1; - } -} - -.single-text { - display: inline-block; - opacity: 1; -} - -.fs_loop { - cursor: pointer; -} - -.container .album { - font-family: "Poppins", "Noto Sans JP", "Helvetica Neue", "Helvetica", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Meiryo", sans-serif; - font-size: clamp(1.5px, calc(3vw - 1px), 15px); - margin-left: 10px; - cursor: pointer; - white-space: nowrap; - overflow-x: scroll; - -ms-overflow-style: none; /* Scrollbar hidden (IE・Edge) */ - scrollbar-width: none; /* Scrollbar hidden (Firefox) */ -} - -.container .album::-webkit-scrollbar{ /* Scrollbar hidden (Chrome・Safari) */ - display: none; -} - -.container .fs_album { - font-size: 0; -} - -.fscontainer .album { - font-size: 0; -} - -.container .fs_album_container { - font-size: 0; - display: none; -} - -.fscontainer .fs_album_container { - display: flex; - justify-content: flex-start; - align-items: center; - font-size: clamp(2px, calc(4vw - 1.3px), 20px); -} - -.fscontainer .fs_album { - margin-right: 40px; - cursor: pointer; - white-space: nowrap; - overflow-x: scroll; - -ms-overflow-style: none; /* Scrollbar hidden (IE・Edge) */ - scrollbar-width: none; /* Scrollbar hidden (Firefox) */ -} - -.container .fs_album::-webkit-scrollbar{ /* Scrollbar hidden (Chrome・Safari) */ - display: none; -} - -.container .queue { - font-size: 0; -} - -.fscontainer .queue { - font-size: clamp(1.5px, calc(3vw - 1px), 15px); -} - -.container .time_container { - font-family: "Lekton", monospace; - display: flex; - justify-content: flex-start; - align-items: center; - font-size: clamp(1.75px, calc(3.5vw - 1.15px), 17.5px); -} - -.container .fs_time_container { - font-size: 0; -} - -.fscontainer .time_container { - font-size: 0; -} - -.fscontainer .fs_time_container { - font-family: "Lekton", monospace; - display: flex; - justify-content: flex-start; - align-items: center; - margin-top: 0.5em; - margin-bottom: 2em; - font-size: clamp(2px, calc(4vw - 1.3px), 20px); -} - -.container .endtime { - margin-left: 5px; - text-align: right; -} - -.container .endtime::before { - content: "-"; - padding-right: 5px; -} - -.fscontainer .endtime { - margin-left: auto; - text-align: right; -} - -/* control button */ -.play-pause-button { - font-size: clamp(2px, 4vw, 20px); - background: none; - border: none; - padding: 0; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; -} - -.container .play-pause-button{ - font-size: clamp(1.5px, 3vw, 15px); - padding-left: clamp(1px, 1vw, 5px); - padding-right: clamp(1px, 1vw, 5px); -} - -.fscontainer .play-pause-button { - position: relative; - top: 35px; -} - -.play-pause-icon { - position: relative; - width: 8vw; - max-width: 2em; - height: 9vw; - max-height: 2.2em; -} - -.bar { - position: absolute; - background: white; - width: 0.9em; - height: 2.2em; - transition: all 0.3s ease-in-out; -} - -.bar-left { - left: 0.12em; - clip-path: polygon(0% 0%, 100% 26%, 100% 74%, 0% 100%); -} - -.bar-right { - right: 0.12em; - clip-path: polygon(0% 25%, 100% 50%, 0% 75%); -} - -.playing .bar-left, -.playing .bar-right { - clip-path: inset(0 0 0 0); - width: 0.5em; -} +@import '../player-style.css'; </style> diff --git a/src/player-style.css b/src/player-style.css @@ -0,0 +1,260 @@ +/* overall frame */ +.container { + position: fixed; + bottom: 0; + width: 100%; + height: 10vw; + max-height: 60px; + background: #000000; + border-top: #404040 solid 2px; + display: flex; + align-items: center; + justify-content: center; + padding-top: clamp(1px, 2vw, 10px); + padding-bottom: clamp(1px, 2vw, 10px); + flex-direction: row; +} + +.fscontainer { + height: auto; + display: flex; + flex-direction: column; + align-items: center; + padding: 30px; + background: #000000; +} + + +/* info_box */ +.container .info_box { + margin-left: 10px; + padding: 0px 10px 0px 0px; + width: 70vw; + max-width: 300px; +} + +.fscontainer .info_box { + position: relative; + top: 10px; + margin: 5px; + width: 100%; + max-width: 500px; +} + + +/* title */ +.title { + position: relative; + width: 100%; + display: flex; + align-items: center; + cursor: pointer; +} + +.container .title { + font-size: clamp(2px, calc(4vw - 1.3px), 20px); +} + +.fscontainer .title { + font-size: clamp(3px, calc(6vw - 2px), 30px); +} + + +/* time */ +.container .time_container { + font-family: "Lekton", monospace; + display: flex; + justify-content: flex-start; + align-items: center; + font-size: clamp(1.75px, calc(3.5vw - 1.15px), 17.5px); +} + +.fscontainer .fs_time_container { + font-family: "Lekton", monospace; + display: flex; + justify-content: flex-start; + align-items: center; + margin-top: 1em; + margin-bottom: 2em; + font-size: clamp(2px, calc(4vw - 1.3px), 20px); +} + +.container .fs_time_container, +.fscontainer .time_container { + font-size: 0; +} + +.container .nowtime, +.container .endtime { + padding-top: min(0.15vw, 2px); +} + +.container .endtime { + margin-left: 5px; + text-align: right; +} + +.container .endtime::before { + content: "-"; + padding-right: 5px; +} + +.fscontainer .endtime { + margin-left: auto; + text-align: right; +} + + +/* album */ +.container .album { + font-family: "Poppins", "Noto Sans JP", "Helvetica Neue", "Helvetica", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Meiryo", sans-serif; + font-size: clamp(1.5px, calc(3vw - 1px), 15px); + margin-left: 10px; + cursor: pointer; +} + +.fscontainer .fs_album_container { + display: flex; + justify-content: flex-start; + align-items: center; + font-size: clamp(2px, calc(4vw - 1.3px), 20px); +} + +.fscontainer .fs_album { + margin-right: clamp(2px, calc(2vw), 12px); + cursor: pointer; +} + +.container .fs_album_container, +.fscontainer .album { + font-size: 0; + display: none; +} + +.fs_loop, +.fs_fav { + cursor: pointer; + padding-left: clamp(2px, calc(2vw), 12px); + margin-top: 4px; +} + +svg { + width: clamp(2px, calc(6vw), 30px); + height: clamp(2px, calc(6vw), 30px); +} + + +/* control button */ +.play-pause-button { + background: none; + border: none; + padding: 0; + cursor: pointer; +} + +.container .play-pause-button { + font-size: clamp(1.5px, 3vw, 15px); + padding-left: clamp(1px, 1vw, 5px); + padding-right: clamp(1px, 1vw, 5px); +} + +.fscontainer .play-pause-button { + font-size: clamp(2px, 4vw, 20px); + position: relative; + top: 35px; + padding-bottom: 30px; +} + +.play-pause-icon { + position: relative; + width: 8vw; + max-width: 2em; + height: 9vw; + max-height: 2.2em; +} + +.bar { + position: absolute; + background: white; + width: 0.9em; + height: 2.2em; + transition: all 0.3s ease-in-out; +} + +.bar-left { + left: 0.12em; + clip-path: polygon(0% 0%, 100% 26%, 100% 74%, 0% 100%); +} + +.bar-right { + right: 0.12em; + clip-path: polygon(0% 25%, 100% 50%, 0% 75%); +} + +.playing .bar-left, +.playing .bar-right { + clip-path: inset(0 0 0 0); + width: 0.5em; +} + + +/* slide animation */ +.slide-down { + animation: slideDown 0.25s ease forwards; +} + +.slide-up { + animation: slideUp 0.25s ease forwards; +} + +@keyframes slideDown { + 0% { + transform: translateY(-100px); + opacity: 0; + } + + 100% { + transform: translateY(0); + } + + 40%, + 100% { + opacity: 1; + } +} + +@keyframes slideUp { + 0% { + transform: translateY(100px); + opacity: 0; + } + + 100% { + transform: translateY(0); + } + + 40%, + 100% { + opacity: 1; + } +} + + +/* scrollbar hidden */ +.title, +.album, +.fs_album { + white-space: nowrap; + overflow-x: scroll; + /* Scrollbar hidden (IE・Edge) */ + -ms-overflow-style: none; + /* Scrollbar hidden (Firefox) */ + scrollbar-width: none; +} + +.title::-webkit-scrollbar, +.album::-webkit-scrollbar, +.fs_album::-webkit-scrollbar { + /* Scrollbar hidden (Chrome・Safari) */ + display: none; +}+ \ No newline at end of file diff --git a/src/style.css b/src/style.css @@ -12,6 +12,8 @@ body { background: #000000; -webkit-text-size-adjust: none; user-select: none; + -webkit-user-select: none; + -webkit-tap-highlight-color: transparent; } @@ -111,7 +113,7 @@ body { font-weight: 500; transform: translateX(100%); transition: transform 0.4s ease; - z-index: -10; + z-index: -20; } .menu.open {