update: responsive ui improvement

This commit is contained in:
Alikia2x 2024-05-12 19:07:32 +08:00
parent b9243b35a6
commit 17a3e45d5e
5 changed files with 69 additions and 100 deletions

View File

@ -1,5 +1,4 @@
<script lang="ts"> <script lang="ts">
import localforage from '$lib/storage';
import type { Writable } from 'svelte/store'; import type { Writable } from 'svelte/store';
export let coverPath: Writable<string>; export let coverPath: Writable<string>;
let path: string = ''; let path: string = '';
@ -9,21 +8,6 @@
}); });
</script> </script>
<img class="cover" src={path} alt="封面" /> <img class="absolute shadow-md select-none z-10 object-cover rounded-2xl max-h-[calc(94vh-18rem)] md:max-h-[calc(94vh-20rem)] xl:w-auto max-w-[90%] md:max-w-[75%] xl:max-w-[37vw]
bottom-72 md:bottom-80
<style> left-1/2 translate-x-[-50%] xl:left-[25vw]" src={path} alt="封面" />
.cover {
user-select: none;
position: absolute;
z-index: 1;
width: 55vh;
min-width: 27vw;
min-height: 27vw;
object-fit: cover;
left: 10vw;
top: 40vh;
transform: translate(0, -50%);
border-radius: 1rem;
box-shadow: 0 0 1rem 0.5rem rgba(0, 0, 0, 0.1);
}
</style>

View File

@ -9,8 +9,10 @@
export let volume: number = 1; export let volume: number = 1;
export let clickPlay: Function; export let clickPlay: Function;
export let adjustProgress: Function; export let adjustProgress: Function;
export let adjustRealProgress: Function;
export let adjustVolume: Function; export let adjustVolume: Function;
let onSlide = false; export let onSlide: boolean;
export let setOnSlide: Function;
let progressBar: HTMLInputElement; let progressBar: HTMLInputElement;
let volumeBar: HTMLInputElement; let volumeBar: HTMLInputElement;
@ -18,12 +20,16 @@
adjustProgress(e.target.value / (duration + 0.001)); adjustProgress(e.target.value / (duration + 0.001));
} }
function progressBarOnInput(e: any) {
adjustRealProgress(e.target.value / (duration + 0.001));
}
function volumeBarOnChange(e: any) { function volumeBarOnChange(e: any) {
adjustVolume(e.target.value); adjustVolume(e.target.value);
} }
</script> </script>
<div class="interactive-box"> <div class="absolute select-none bottom-2 h-60 w-[86vw] left-[7vw] lg:w-[76vw] lg:left-[12vw] xl:w-[37vw] xl:left-[7vw]">
<div class="song-info"> <div class="song-info">
<span class="song-name text-shadow">{name}</span><br /> <span class="song-name text-shadow">{name}</span><br />
<span class="song-author">{singer}</span> <span class="song-author">{singer}</span>
@ -34,10 +40,11 @@
class="progress-bar shadow-md" class="progress-bar shadow-md"
bind:this={progressBar} bind:this={progressBar}
on:change={progressBarOnChange} on:change={progressBarOnChange}
on:mousedown={() => (onSlide = true)} on:input={progressBarOnInput}
on:mousedown={() => setOnSlide(true)}
on:mouseup={() => { on:mouseup={() => {
setTimeout(() => { setTimeout(() => {
onSlide = false; setOnSlide(false);
}, 50); }, 50);
}} }}
type="range" type="range"
@ -195,13 +202,4 @@
.time-total { .time-total {
right: 0; right: 0;
} }
.interactive-box {
user-select: none;
position: absolute;
width: 55vh;
min-width: 27vw;
top: 69vh;
height: 15rem;
left: 10vw;
}
</style> </style>

View File

@ -37,12 +37,8 @@
for (let i = 0; i < lyrics.length; i++) { for (let i = 0; i < lyrics.length; i++) {
const offset = Math.abs(i - currentLyricIndex); const offset = Math.abs(i - currentLyricIndex);
const blurRadius = Math.min(offset * 1, 16); const blurRadius = Math.min(offset * 1, 16);
const fontSize = i === currentLyricIndex ? '3.5rem' : '3rem';
const lineHeight = i === currentLyricIndex ? '4.5rem' : '4rem';
if (refs[i]) { if (refs[i]) {
refs[i].style.filter = `blur(${blurRadius}px)`; refs[i].style.filter = `blur(${blurRadius}px)`;
refs[i].style.fontSize = fontSize;
refs[i].style.lineHeight = lineHeight;
} }
} }
if (!found) { if (!found) {
@ -60,7 +56,10 @@
</script> </script>
{#if lyrics && originalLyrics} {#if lyrics && originalLyrics}
<div class="lyrics" style="overflow-y: auto"> <div
class="absolute top-0 w-screen xl:w-[52vw] xl:left-[45vw] xl:px-[3vw] h-screen font-sans
text-left scroll-smooth no-scrollbar overflow-y-auto"
>
{#each lyrics as lyric, i} {#each lyrics as lyric, i}
<p bind:this={_refs[i]} class={getClass(i, progress)}> <p bind:this={_refs[i]} class={getClass(i, progress)}>
{lyric} {lyric}
@ -70,27 +69,18 @@
{/if} {/if}
<style> <style>
.lyrics { .no-scrollbar {
position: absolute;
width: 52vw;
left: 45vw;
padding-left: 3vw;
padding-right: 3vw;
height: 100vh;
font-family: sans-serif;
text-align: left;
scroll-behavior: smooth;
scrollbar-width: none; scrollbar-width: none;
} }
::-webkit-scrollbar { .no-scrollbar::-webkit-scrollbar {
width: 0; width: 0;
} }
.current-lyric { .current-lyric {
position: relative; position: relative;
color: white; color: white;
font-weight: 600; font-weight: 600;
font-size: 3.5rem; font-size: 2rem;
line-height: 4.5rem; line-height: 2.5rem;
top: 1rem; top: 1rem;
transition: 0.2s; transition: 0.2s;
margin: 2rem 0.3rem; margin: 2rem 0.3rem;
@ -117,4 +107,11 @@
transition: 0.2s; transition: 0.2s;
margin: 2rem 0rem; margin: 2rem 0rem;
} }
@media (min-width: 1024px) {
.current-lyric {
font-size: 3.5rem;
line-height: 4.5rem;
}
}
</style> </style>

View File

@ -1,51 +1,18 @@
<script lang="ts"> <script lang="ts">
import { onMount } from 'svelte'; import localforage from "$lib/storage";
import localforage from 'localforage'; let musicList;
import Background from '$lib/components/background.svelte';
let audioInput: any;
let coverInput: any;
const audioId = 'd5a2e306-ddea-4fc3-9927-c79dcb3a4071';
// Initialize IndexedDB function extractId(key: string) {
localforage.config({ return key.split('-').pop();
driver: localforage.INDEXEDDB,
name: 'audioDB'
});
onMount(() => {
// Handle audio input change
audioInput.addEventListener('change', function (e: any) {
const file: File = e.target.files[0];
if (file) {
localforage.setItem(audioId + '-file', file);
} }
}); localforage.iterate(function (value, key, iterationNumber) {
console.log(extractId(key));
coverInput.addEventListener('change', function (e: any) { })
const file = e.target.files[0];
if (file) {
localforage.setItem(audioId + '-cover', file);
}
});
return () => {
;
};
});
</script> </script>
<p> <div
Select Audio File: class="absolute w-screen md:w-2/3 left-0 md:left-[16.6667%] px-[3%] md:px-0 top-16"
<input type="file" bind:this={audioInput} /> >
</p> <h1>AquaVox</h1>
<p> <h2>音乐库</h2>
Select Cover File: </div>
<input type="file" bind:this={coverInput} />
</p>
<input
type="text"
placeholder="Input song id"
id="audioId"
value="d5a2e306-ddea-4fc3-9927-c79dcb3a4071"
style="width: 36ch"
/>
<Background coverId={audioId} />

View File

@ -24,6 +24,7 @@
let prepared: string[] = []; let prepared: string[] = [];
let originalLyrics: Line[]; let originalLyrics: Line[];
let lyricsText: string[] = []; let lyricsText: string[] = [];
let onAdjustingProgress = false;
const coverPath = writable(''); const coverPath = writable('');
let mainInterval: ReturnType<typeof setInterval>; let mainInterval: ReturnType<typeof setInterval>;
@ -131,16 +132,30 @@
} }
} }
function adjustRealProgress(progress: number) {
if (audioPlayer) {
currentProgress = duration * progress;
}
}
function adjustVolume(targetVolume: number) { function adjustVolume(targetVolume: number) {
if (audioPlayer) { if (audioPlayer) {
audioPlayer.volume = targetVolume; audioPlayer.volume = targetVolume;
} }
} }
function setOnSlide(value: boolean) {
onAdjustingProgress = value;
}
$: { $: {
clearInterval(mainInterval); clearInterval(mainInterval);
mainInterval = setInterval(() => { mainInterval = setInterval(() => {
if (audioPlayer !== null && audioPlayer.currentTime !== undefined) { if (
audioPlayer !== null &&
audioPlayer.currentTime !== undefined &&
onAdjustingProgress === false
) {
currentProgress = audioPlayer.currentTime; currentProgress = audioPlayer.currentTime;
} }
}, 100); }, 100);
@ -156,6 +171,10 @@
readDB(); readDB();
</script> </script>
<svelte:head>
<title>{name} - Aquavox</title>
</svelte:head>
<Background coverId={audioId} /> <Background coverId={audioId} />
<Cover {coverPath} /> <Cover {coverPath} />
<InteractiveBox <InteractiveBox
@ -168,7 +187,13 @@
{paused} {paused}
{adjustProgress} {adjustProgress}
{adjustVolume} {adjustVolume}
{adjustRealProgress}
onSlide={onAdjustingProgress}
{setOnSlide}
/> />
<Lyrics lyrics={lyricsText} {originalLyrics} progress={currentProgress} />
<audio <audio
bind:this={audioPlayer} bind:this={audioPlayer}
controls controls
@ -178,5 +203,3 @@
audioPlayer.pause(); audioPlayer.pause();
}} }}
></audio> ></audio>
<Lyrics lyrics={lyricsText} {originalLyrics} progress={currentProgress} />