fix: optimize thumbnail animation

This commit is contained in:
Phan An 2022-07-16 17:44:45 +02:00
parent 6332abe74c
commit 05c298ca2c
No known key found for this signature in database
GPG key ID: A81E4477F0BB6FDC
14 changed files with 42 additions and 33 deletions

View file

@ -17,4 +17,4 @@ createApp(App)
*/
.mount('#app')
navigator.serviceWorker.register('./sw.js').then(() => console.log('Service Worker Registered'))
navigator.serviceWorker.register('./sw.js')

View file

@ -1,6 +1,6 @@
<template>
<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">
<icon :icon="faBars"/>
</span>
@ -54,7 +54,6 @@ const showAboutDialog = () => eventBus.emit('MODAL_SHOW_ABOUT_KOEL')
h1.brand {
flex: 1;
font-size: 1.7rem;
font-weight: var(--font-weight-thin);
opacity: 0;
line-height: var(--header-height);
text-align: center;

View file

@ -1,6 +1,6 @@
<template>
<section id="albumsWrapper">
<ScreenHeader>
<ScreenHeader layout="collapsed">
Albums
<template v-slot:controls>
<ViewModeSwitch v-model="viewMode"/>

View file

@ -1,6 +1,6 @@
<template>
<section id="artistsWrapper">
<ScreenHeader>
<ScreenHeader layout="collapsed">
Artists
<template v-slot:controls>
<ViewModeSwitch v-model="viewMode"/>

View file

@ -1,6 +1,6 @@
<template>
<section id="homeWrapper">
<ScreenHeader>{{ greeting }}</ScreenHeader>
<ScreenHeader layout="collapsed">{{ greeting }}</ScreenHeader>
<div class="main-scroll-wrap" @scroll="scrolling">
<ScreenEmptyState v-if="libraryEmpty">

View file

@ -1,6 +1,6 @@
<template>
<section id="uploadWrapper">
<ScreenHeader>
<ScreenHeader layout="collapsed">
Upload Media
<template v-slot:controls>

View file

@ -1,6 +1,6 @@
<template>
<section id="usersWrapper">
<ScreenHeader>
<ScreenHeader layout="collapsed">
Users
<ControlsToggle :showing-controls="showingControls" @toggleControls="toggleControls"/>

View file

@ -1,6 +1,6 @@
<template>
<section id="youtubeWrapper">
<screen-header>{{ title }}</screen-header>
<ScreenHeader layout="collapsed">{{ title }}</ScreenHeader>
<div id="player">
<ScreenEmptyState data-testid="youtube-placeholder">

View file

@ -1,7 +1,7 @@
<template>
<section id="searchExcerptsWrapper">
<ScreenHeader>
<span v-if="q">Search Results for <strong>{{ q }}</strong></span>
<ScreenHeader layout="collapsed">
<span v-if="q">Searching for <span class="text-thin">{{ q }}</span></span>
<span v-else>Search</span>
</ScreenHeader>

View file

@ -1,7 +1,7 @@
<template>
<section id="songResultsWrapper">
<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"/>
<template v-slot:thumbnail>
@ -62,9 +62,3 @@ const decodedQ = computed(() => decodeURIComponent(q.value))
searchStore.resetSongResultState()
searchStore.songSearch(decodedQ.value)
</script>
<style lang="scss" scoped>
.q {
font-weight: var(--font-weight-thin);
}
</style>

View file

@ -32,26 +32,28 @@ const { hasThumbnail } = toRefs(props)
<style lang="scss">
header.screen-header {
--transition-duration: .3s;
@media (prefers-reduced-motion) {
--transition-duration: 0;
}
display: flex;
align-items: flex-end;
border-bottom: 1px solid var(--color-bg-secondary);
position: relative;
align-content: stretch;
line-height: normal;
gap: 1.5rem;
padding: .8rem 1rem .8rem 0;
will-change: height;
padding: 1.8rem;
&.expanded {
padding: 1.8rem;
.thumbnail-wrapper {
margin-right: 1.5rem;
width: 192px;
}
h1.name {
font-size: 4rem;
font-weight: bold;
> * {
transform: scale(1);
}
}
.meta {
@ -66,13 +68,18 @@ header.screen-header {
.thumbnail-wrapper {
overflow: hidden;
width: 0;
display: none;
will-change: width, height;
transition: width .3s;
width: 0;
transition: width var(--transition-duration);
box-shadow: 0 10px 20px 0 rgba(0, 0, 0, 0.3);
border-radius: 5px;
> * {
transform: scale(0);
transform-origin: bottom left;
transition: transform var(--transition-duration), width var(--transition-duration);
}
&.non-empty {
display: block;
}
@ -87,11 +94,12 @@ header.screen-header {
}
h1.name {
font-size: 2.75rem;
font-weight: var(--font-weight-thin);
font-size: 4rem;
font-weight: var(--font-weight-bold);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin-right: 1.5rem;
}
.heading-wrapper {

View file

@ -1,5 +1,5 @@
<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}`}"/>
</div>
</template>
@ -26,6 +26,8 @@ const layout = computed<'mono' | 'tiles'>(() => displayedThumbnails.value.length
aspect-ratio: 1/1;
display: grid;
overflow: hidden;
background-size: cover;
background-repeat: no-repeat;
&.tiles {
grid-template-columns: 1fr 1fr;
@ -33,6 +35,7 @@ const layout = computed<'mono' | 'tiles'>(() => displayedThumbnails.value.length
span {
display: block;
will-change: transform; // fix anti-aliasing problem with background images
width: 100%;
height: 100%;
background-size: cover;

View file

@ -277,6 +277,10 @@ label {
&uppercase {
text-transform: uppercase !important;
}
&thin {
font-weight: var(--font-weight-thin) !important;
}
}
.d- {

View file

@ -15,6 +15,7 @@
--font-weight-thin: 100;
--font-weight-light: 300;
--font-weight-normal: 500;
--font-weight-bold: 700;
--header-height: 48px;
--footer-height: 64px;