fix(style): use buttons, add spacings and new play indicator animation for track row

This commit is contained in:
ArneBo 2025-02-23 00:01:13 +01:00
parent 7e61a59b68
commit 75d4ac5467
5 changed files with 166 additions and 44 deletions

View File

@ -4,5 +4,9 @@
<div class="audio-bar" /> <div class="audio-bar" />
<div class="audio-bar" /> <div class="audio-bar" />
<div class="audio-bar" /> <div class="audio-bar" />
<div class="audio-bar" />
<div class="audio-bar" />
<div class="audio-bar" />
<div class="audio-bar" />
</div> </div>
</template> </template>

View File

@ -6,12 +6,14 @@ import { computed, ref } from 'vue'
import usePlayOptions from '~/composables/audio/usePlayOptions' import usePlayOptions from '~/composables/audio/usePlayOptions'
import TrackFavoriteIcon from '~/components/favorites/TrackFavoriteIcon.vue'
import PlayIndicator from '~/components/audio/track/PlayIndicator.vue'
import PlayButton from '~/components/audio/PlayButton.vue'
import { usePlayer } from '~/composables/audio/player' import { usePlayer } from '~/composables/audio/player'
import { useQueue } from '~/composables/audio/queue' import { useQueue } from '~/composables/audio/queue'
import { useStore } from '~/store' import { useStore } from '~/store'
import TrackFavoriteIcon from '~/components/favorites/TrackFavoriteIcon.vue'
import PlayIndicator from '~/components/audio/track/PlayIndicator.vue'
import PlayButton from '~/components/audio/PlayButton.vue'
import Button from '~/components/ui/Button.vue'
const store = useStore() const store = useStore()
@ -84,32 +86,29 @@ const hover = ref(false)
!hover !hover
" "
/> />
<button <Button
v-else-if=" v-else-if="
!isPlaying && !isPlaying &&
active && active &&
!hover !hover
" "
class="ui really tiny basic icon button play-button paused" :icon="isPlaying && active && hover ? 'bi-play-fill' : 'bi-pause-fill'"
> :class="[{ paused: isPlaying && active && hover }, 'ui', 'play-button']"
<i class="bi bi-play-fill" /> />
</button> <Button
<button
v-else-if=" v-else-if="
isPlaying && isPlaying &&
active && active &&
hover hover
" "
class="ui really tiny basic icon button play-button" icon="bi-pause-fill"
> class="ui play-button"
<i class="bi bi-pause-fill" /> />
</button> <Button
<button
v-else-if="hover" v-else-if="hover"
class="ui really tiny basic icon button play-button" icon="bi-play-fill"
> class="ui play-button"
<i class="bi bi-play-fill" /> />
</button>
<span <span
v-else-if="showPosition" v-else-if="showPosition"
class="track-position" class="track-position"
@ -127,26 +126,20 @@ const hover = ref(false)
> >
<img <img
v-if="showArt && track.cover?.urls.original" v-if="showArt && track.cover?.urls.original"
v-lazy="store.getters['instance/absoluteUrl'](track.cover.urls.medium_square_crop)" v-lazy="store.getters['instance/absoluteUrl'](track.cover.urls.small_square_crop)"
alt="" :alt="track.title"
class="ui artist-track mini image" class="track_image"
> >
<img <img
v-else-if="showArt && track.album?.cover?.urls.original" v-else-if="showArt && track.album?.cover?.urls.original"
v-lazy="store.getters['instance/absoluteUrl'](track.album.cover.urls.medium_square_crop)" v-lazy="store.getters['instance/absoluteUrl'](track.album.cover.urls.small_square_crop)"
alt="" alt=""
class="ui artist-track mini image" class="track_image"
>
<img
v-else-if="showArt && track.artist_credit?.length && track.artist_credit[0].artist.cover?.urls.original"
v-lazy="store.getters['instance/absoluteUrl'](track.artist_credit[0].artist.cover.urls.medium_square_crop) "
alt=""
class="ui artist-track mini image"
> >
<img <img
v-else-if="showArt" v-else-if="showArt"
alt="" alt=""
class="ui artist-track mini image" class="track_image"
src="../../../assets/audio/default-cover.png" src="../../../assets/audio/default-cover.png"
> >
</div> </div>
@ -240,6 +233,7 @@ const hover = ref(false)
.row > div { .row > div {
/* total height 64px, according to designs on penpot */ /* total height 64px, according to designs on penpot */
margin-bottom: 8px; margin-bottom: 8px;
margin-right: 8px;
height: 48px; height: 48px;
} }
</style> </style>

View File

@ -187,7 +187,7 @@ const updatePage = (page: number) => {
<Loader v-if="isLoading" /> <Loader v-if="isLoading" />
<Table <Table
:grid-template-columns="['48px', '48px', 'auto', 'auto', 'auto', '48px', '64px', '48px']" :grid-template-columns="['48px', '56px', 'auto', 'auto', 'auto', '56px', '64px', '48px']"
:header-props="{ 'table-header': true }" :header-props="{ 'table-header': true }"
> >
<template #header> <template #header>

View File

@ -1,13 +1,15 @@
#audio-bars { #audio-bars {
height: 1em; height: 48px;
display: flex; display: flex;
width: 12px; width: 48px;
align-items: center;
padding: 8px;
} }
.audio-bar { .audio-bar {
background: var(--main-color); background: var(--main-color);
width: 3px; width: 8px;
height: 1em; height: 100%;
animation: sound 1s cubic-bezier(.17,.37,.43,.67) infinite alternate; animation: sound 1s cubic-bezier(.17,.37,.43,.67) infinite alternate;
will-change: opacity, transform; will-change: opacity, transform;
transform-origin: bottom; transform-origin: bottom;
@ -24,7 +26,129 @@
} }
} }
.audio-bar:nth-child(1) { animation-duration: 0.4s; } /* Keyframes for individual bars */
.audio-bar:nth-child(2) { animation-duration: 0.2s; } @keyframes sound1 {
.audio-bar:nth-child(3) { animation-duration: 1.0s; } 0% {
.audio-bar:nth-child(4) { animation-duration: 0.3s; } opacity: .35;
transform: scaleY(0.1) translateZ(0);
}
100% {
opacity: 1;
transform: scaleY(0.7); /* Scale to 70% of the container height */
}
}
@keyframes sound2 {
0% {
opacity: .35;
transform: scaleY(0.1) translateZ(0);
}
100% {
opacity: 1;
transform: scaleY(0.8); /* Scale to 80% of the container height */
}
}
@keyframes sound3 {
0% {
opacity: .35;
transform: scaleY(0.1) translateZ(0);
}
100% {
opacity: 1;
transform: scaleY(1); /* Scale to 100% of the container height */
}
}
@keyframes sound4 {
0% {
opacity: .35;
transform: scaleY(0.1) translateZ(0);
}
100% {
opacity: 1;
transform: scaleY(0.9); /* Scale to 90% of the container height */
}
}
@keyframes sound5 {
0% {
opacity: .35;
transform: scaleY(0.1) translateZ(0);
}
100% {
opacity: 1;
transform: scaleY(0.9); /* Scale to 90% of the container height */
}
}
@keyframes sound6 {
0% {
opacity: .35;
transform: scaleY(0.1) translateZ(0);
}
100% {
opacity: 1;
transform: scaleY(0.8); /* Scale to 80% of the container height */
}
}
@keyframes sound7 {
0% {
opacity: .35;
transform: scaleY(0.1) translateZ(0);
}
100% {
opacity: 1;
transform: scaleY(0.7); /* Scale to 70% of the container height */
}
}
@keyframes sound8 {
0% {
opacity: .35;
transform: scaleY(0.1) translateZ(0);
}
100% {
opacity: 1;
transform: scaleY(0.6); /* Scale to 60% of the container height */
}
}
/* Bass frequencies - slower attack, higher elevation */
.audio-bar:nth-child(1) {
animation-duration: 0.8s;
animation-name: sound1;
}
.audio-bar:nth-child(2) {
animation-duration: 0.7s;
animation-name: sound2;
}
/* Mid frequencies - moderate attack and elevation */
.audio-bar:nth-child(3) {
animation-duration: 0.6s;
animation-name: sound3;
}
.audio-bar:nth-child(4) {
animation-duration: 0.5s;
animation-name: sound4;
}
.audio-bar:nth-child(5) {
animation-duration: 0.4s;
animation-name: sound5;
}
/* High frequencies - quicker attack, lower elevation */
.audio-bar:nth-child(6) {
animation-duration: 0.4s;
animation-name: sound6;
}
.audio-bar:nth-child(7) {
animation-duration: 0.3s;
animation-name: sound7;
}
.audio-bar:nth-child(8) {
animation-duration: 0.2s;
animation-name: sound8;
}

View File

@ -62,12 +62,12 @@
height: 100%; height: 100%;
vertical-align: middle; vertical-align: middle;
} }
.ui.artist-track.mini.image { .image.column {
height: 40px; padding: 8px;
margin-right: 8px; }
margin-top: 4px; .track_image {
height: 40px;
} }
.image.left.floated.column { .image.left.floated.column {
} }