mirror of
https://github.com/koel/koel
synced 2025-02-17 22:08:28 +00:00
fix: optimize thumbnail animation
This commit is contained in:
parent
6332abe74c
commit
05c298ca2c
14 changed files with 42 additions and 33 deletions
|
@ -17,4 +17,4 @@ createApp(App)
|
||||||
*/
|
*/
|
||||||
.mount('#app')
|
.mount('#app')
|
||||||
|
|
||||||
navigator.serviceWorker.register('./sw.js').then(() => console.log('Service Worker Registered'))
|
navigator.serviceWorker.register('./sw.js')
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<header id="mainHeader">
|
<header id="mainHeader">
|
||||||
<h1 class="brand">Koel</h1>
|
<h1 class="brand text-thin">Koel</h1>
|
||||||
<span class="hamburger" role="button" title="Show or hide the sidebar" @click="toggleSidebar">
|
<span class="hamburger" role="button" title="Show or hide the sidebar" @click="toggleSidebar">
|
||||||
<icon :icon="faBars"/>
|
<icon :icon="faBars"/>
|
||||||
</span>
|
</span>
|
||||||
|
@ -54,7 +54,6 @@ const showAboutDialog = () => eventBus.emit('MODAL_SHOW_ABOUT_KOEL')
|
||||||
h1.brand {
|
h1.brand {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
font-size: 1.7rem;
|
font-size: 1.7rem;
|
||||||
font-weight: var(--font-weight-thin);
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
line-height: var(--header-height);
|
line-height: var(--header-height);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<section id="albumsWrapper">
|
<section id="albumsWrapper">
|
||||||
<ScreenHeader>
|
<ScreenHeader layout="collapsed">
|
||||||
Albums
|
Albums
|
||||||
<template v-slot:controls>
|
<template v-slot:controls>
|
||||||
<ViewModeSwitch v-model="viewMode"/>
|
<ViewModeSwitch v-model="viewMode"/>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<section id="artistsWrapper">
|
<section id="artistsWrapper">
|
||||||
<ScreenHeader>
|
<ScreenHeader layout="collapsed">
|
||||||
Artists
|
Artists
|
||||||
<template v-slot:controls>
|
<template v-slot:controls>
|
||||||
<ViewModeSwitch v-model="viewMode"/>
|
<ViewModeSwitch v-model="viewMode"/>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<section id="homeWrapper">
|
<section id="homeWrapper">
|
||||||
<ScreenHeader>{{ greeting }}</ScreenHeader>
|
<ScreenHeader layout="collapsed">{{ greeting }}</ScreenHeader>
|
||||||
|
|
||||||
<div class="main-scroll-wrap" @scroll="scrolling">
|
<div class="main-scroll-wrap" @scroll="scrolling">
|
||||||
<ScreenEmptyState v-if="libraryEmpty">
|
<ScreenEmptyState v-if="libraryEmpty">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<section id="uploadWrapper">
|
<section id="uploadWrapper">
|
||||||
<ScreenHeader>
|
<ScreenHeader layout="collapsed">
|
||||||
Upload Media
|
Upload Media
|
||||||
|
|
||||||
<template v-slot:controls>
|
<template v-slot:controls>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<section id="usersWrapper">
|
<section id="usersWrapper">
|
||||||
<ScreenHeader>
|
<ScreenHeader layout="collapsed">
|
||||||
Users
|
Users
|
||||||
<ControlsToggle :showing-controls="showingControls" @toggleControls="toggleControls"/>
|
<ControlsToggle :showing-controls="showingControls" @toggleControls="toggleControls"/>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<section id="youtubeWrapper">
|
<section id="youtubeWrapper">
|
||||||
<screen-header>{{ title }}</screen-header>
|
<ScreenHeader layout="collapsed">{{ title }}</ScreenHeader>
|
||||||
|
|
||||||
<div id="player">
|
<div id="player">
|
||||||
<ScreenEmptyState data-testid="youtube-placeholder">
|
<ScreenEmptyState data-testid="youtube-placeholder">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<section id="searchExcerptsWrapper">
|
<section id="searchExcerptsWrapper">
|
||||||
<ScreenHeader>
|
<ScreenHeader layout="collapsed">
|
||||||
<span v-if="q">Search Results for <strong>{{ q }}</strong></span>
|
<span v-if="q">Searching for <span class="text-thin">{{ q }}</span></span>
|
||||||
<span v-else>Search</span>
|
<span v-else>Search</span>
|
||||||
</ScreenHeader>
|
</ScreenHeader>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<section id="songResultsWrapper">
|
<section id="songResultsWrapper">
|
||||||
<ScreenHeader :layout="headerLayout" has-thumbnail>
|
<ScreenHeader :layout="headerLayout" has-thumbnail>
|
||||||
Songs for <span class="q">{{ decodedQ }}</span>
|
Songs for <span class="text-thin">{{ decodedQ }}</span>
|
||||||
<ControlsToggle :showing-controls="showingControls" @toggleControls="toggleControls"/>
|
<ControlsToggle :showing-controls="showingControls" @toggleControls="toggleControls"/>
|
||||||
|
|
||||||
<template v-slot:thumbnail>
|
<template v-slot:thumbnail>
|
||||||
|
@ -62,9 +62,3 @@ const decodedQ = computed(() => decodeURIComponent(q.value))
|
||||||
searchStore.resetSongResultState()
|
searchStore.resetSongResultState()
|
||||||
searchStore.songSearch(decodedQ.value)
|
searchStore.songSearch(decodedQ.value)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.q {
|
|
||||||
font-weight: var(--font-weight-thin);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -32,26 +32,28 @@ const { hasThumbnail } = toRefs(props)
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
header.screen-header {
|
header.screen-header {
|
||||||
|
--transition-duration: .3s;
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion) {
|
||||||
|
--transition-duration: 0;
|
||||||
|
}
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
border-bottom: 1px solid var(--color-bg-secondary);
|
border-bottom: 1px solid var(--color-bg-secondary);
|
||||||
position: relative;
|
position: relative;
|
||||||
align-content: stretch;
|
align-content: stretch;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
gap: 1.5rem;
|
padding: 1.8rem;
|
||||||
padding: .8rem 1rem .8rem 0;
|
|
||||||
will-change: height;
|
|
||||||
|
|
||||||
&.expanded {
|
&.expanded {
|
||||||
padding: 1.8rem;
|
|
||||||
|
|
||||||
.thumbnail-wrapper {
|
.thumbnail-wrapper {
|
||||||
|
margin-right: 1.5rem;
|
||||||
width: 192px;
|
width: 192px;
|
||||||
}
|
|
||||||
|
|
||||||
h1.name {
|
> * {
|
||||||
font-size: 4rem;
|
transform: scale(1);
|
||||||
font-weight: bold;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.meta {
|
.meta {
|
||||||
|
@ -66,13 +68,18 @@ header.screen-header {
|
||||||
|
|
||||||
.thumbnail-wrapper {
|
.thumbnail-wrapper {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
width: 0;
|
|
||||||
display: none;
|
display: none;
|
||||||
will-change: width, height;
|
width: 0;
|
||||||
transition: width .3s;
|
transition: width var(--transition-duration);
|
||||||
box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.3);
|
box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.3);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
|
||||||
|
> * {
|
||||||
|
transform: scale(0);
|
||||||
|
transform-origin: bottom left;
|
||||||
|
transition: transform var(--transition-duration), width var(--transition-duration);
|
||||||
|
}
|
||||||
|
|
||||||
&.non-empty {
|
&.non-empty {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
@ -87,11 +94,12 @@ header.screen-header {
|
||||||
}
|
}
|
||||||
|
|
||||||
h1.name {
|
h1.name {
|
||||||
font-size: 2.75rem;
|
font-size: 4rem;
|
||||||
font-weight: var(--font-weight-thin);
|
font-weight: var(--font-weight-bold);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
margin-right: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heading-wrapper {
|
.heading-wrapper {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="thumbnail-stack" :class="layout">
|
<div class="thumbnail-stack" :class="layout" :style="{ backgroundImage: `url(${defaultCover})` }">
|
||||||
<span v-for="thumbnail in displayedThumbnails" :style="{ backgroundImage: `url(${thumbnail}`}"/>
|
<span v-for="thumbnail in displayedThumbnails" :style="{ backgroundImage: `url(${thumbnail}`}"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -26,6 +26,8 @@ const layout = computed<'mono' | 'tiles'>(() => displayedThumbnails.value.length
|
||||||
aspect-ratio: 1/1;
|
aspect-ratio: 1/1;
|
||||||
display: grid;
|
display: grid;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
|
||||||
&.tiles {
|
&.tiles {
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
|
@ -33,6 +35,7 @@ const layout = computed<'mono' | 'tiles'>(() => displayedThumbnails.value.length
|
||||||
|
|
||||||
span {
|
span {
|
||||||
display: block;
|
display: block;
|
||||||
|
will-change: transform; // fix anti-aliasing problem with background images
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
|
|
|
@ -277,6 +277,10 @@ label {
|
||||||
&uppercase {
|
&uppercase {
|
||||||
text-transform: uppercase !important;
|
text-transform: uppercase !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&thin {
|
||||||
|
font-weight: var(--font-weight-thin) !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.d- {
|
.d- {
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
--font-weight-thin: 100;
|
--font-weight-thin: 100;
|
||||||
--font-weight-light: 300;
|
--font-weight-light: 300;
|
||||||
--font-weight-normal: 500;
|
--font-weight-normal: 500;
|
||||||
|
--font-weight-bold: 700;
|
||||||
|
|
||||||
--header-height: 48px;
|
--header-height: 48px;
|
||||||
--footer-height: 64px;
|
--footer-height: 64px;
|
||||||
|
|
Loading…
Add table
Reference in a new issue