improve: interactiveBox a11y and style

This commit is contained in:
Alikia2x 2024-05-11 17:42:43 +08:00
parent 6e50a7bdc3
commit 83260dc2dc
5 changed files with 96 additions and 27 deletions

View File

@ -20,7 +20,6 @@
if (file) { if (file) {
const path = URL.createObjectURL(file as File); const path = URL.createObjectURL(file as File);
processImage(16, 4, 96, path, canvas, (resultImageData: ImageData) => { processImage(16, 4, 96, path, canvas, (resultImageData: ImageData) => {
console.log(resultImageData);
localforage.setItem( localforage.setItem(
`${coverId}-cover-cache`, `${coverId}-cover-cache`,
imageDataToBlob(resultImageData) imageDataToBlob(resultImageData)

View File

@ -13,6 +13,7 @@
<style> <style>
.cover { .cover {
user-select: none;
position: absolute; position: absolute;
z-index: 1; z-index: 1;
min-height: 35vh; min-height: 35vh;

View File

@ -7,6 +7,13 @@
export let progress: number = 0; export let progress: number = 0;
export let paused: boolean; export let paused: boolean;
export let clickPlay: Function; export let clickPlay: Function;
export let adjustProgress: Function;
let onSlide = false;
let progressBar: HTMLInputElement;
function progressBarOnChange(e: any) {
adjustProgress(e.target.value / (duration + 0.001));
}
</script> </script>
<div class="interactive-box"> <div class="interactive-box">
@ -16,28 +23,52 @@
</div> </div>
<div class="progress"> <div class="progress">
<div class="time-indicator text-shadow-md time-current">{formatDuration(progress)}</div> <div class="time-indicator text-shadow-md time-current">{formatDuration(progress)}</div>
<div class="progress-bar shadow-md"> <input
<div class="bar" style={`width: ${(progress / (duration + 0.001)) * 100}%;`}></div> class="progress-bar shadow-md"
</div> bind:this={progressBar}
on:change={progressBarOnChange}
on:mousedown={() => (onSlide = true)}
on:mouseup={() => {
setTimeout(() => {
onSlide = false;
}, 50);
}}
type="range"
min="0"
max={duration - 0.2}
step="1"
value={onSlide ? progressBar.value : progress}
/>
<!-- <div class="bar" style={`width: ${(progress / (duration + 0.001)) * 100}%;`}></div> -->
<div class="time-indicator text-shadow-md time-total">{formatDuration(duration)}</div> <div class="time-indicator text-shadow-md time-total">{formatDuration(duration)}</div>
</div> </div>
<div class="controls"> <div class="controls">
<div style="filter: drop-shadow( 0 4px 8px rgba(0, 0, 0, 0.12) );" class="control-btn previous"> <button
style="filter: drop-shadow( 0 4px 8px rgba(0, 0, 0, 0.12) );"
class="control-btn previous"
>
<img class="control-img switch-song-img" src="/previous.svg" alt="上一曲" /> <img class="control-img switch-song-img" src="/previous.svg" alt="上一曲" />
</div> </button>
<div style="filter: drop-shadow( 0 4px 8px rgba(0, 0, 0, 0.12) );" class="control-btn play-btn" on:click={() => clickPlay()}> <button
style="filter: drop-shadow( 0 4px 8px rgba(0, 0, 0, 0.12) );"
class="control-btn play-btn"
on:click={() => clickPlay()}
>
<img class="control-img" src={paused ? '/play.svg' : '/pause.svg'} alt="暂停或播放" /> <img class="control-img" src={paused ? '/play.svg' : '/pause.svg'} alt="暂停或播放" />
</div> </button>
<div style="filter: drop-shadow( 0 4px 8px rgba(0, 0, 0, 0.12) );" class="control-btn next"> <button
style="filter: drop-shadow( 0 4px 8px rgba(0, 0, 0, 0.12) );"
class="control-btn next"
>
<img class="control-img switch-song-img" src="/next.svg" alt="下一曲" /> <img class="control-img switch-song-img" src="/next.svg" alt="下一曲" />
</div> </button>
</div> </div>
</div> </div>
<style> <style>
.controls { .controls {
position: absolute; position: absolute;
top: 9rem; top: 10rem;
width: 100%; width: 100%;
left: 50%; left: 50%;
transform: translate(-50%, 0); transform: translate(-50%, 0);
@ -63,8 +94,7 @@
height: 2.3rem; height: 2.3rem;
width: 2.3rem; width: 2.3rem;
left: 50%; left: 50%;
top: 50%; transform: translate(-50%, 0);
transform: translate(-50%, -50%);
} }
.previous { .previous {
left: 50%; left: 50%;
@ -80,6 +110,7 @@
} }
.song-info { .song-info {
user-select: text;
position: absolute; position: absolute;
width: auto; width: auto;
left: 50%; left: 50%;
@ -107,18 +138,47 @@
height: 2.4rem; height: 2.4rem;
} }
.progress-bar { .progress-bar {
-webkit-appearance: none;
appearance: none;
top: 1.8rem; top: 1.8rem;
position: relative; position: relative;
width: 100%; width: 100%;
height: 0.3rem; height: 0.4rem;
background-color: rgba(255, 255, 255, .5); background-color: rgba(64, 64, 64, 0.5);
color: white;
border-radius: 0.5rem; border-radius: 0.5rem;
overflow: hidden;
cursor: pointer;
transition: 0.3s;
}
.progress-bar:hover {
height: 0.7rem;
}
.progress-bar::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 0.2rem;
height: 0.7rem;
background-color: white;
box-shadow: -700px 0 0 700px white;
cursor: pointer;
}
/* Customize the appearance of the thumb for Firefox */
.progress-bar::-moz-range-thumb {
appearance: none;
width: 0px;
height: 0px;
background-color: white;
box-shadow: -700px 0 0 700px white;
cursor: pointer;
border: none;
} }
.bar { .bar {
background-color: white; background-color: white;
position: absolute; position: absolute;
content: ''; content: '';
height: 0.3rem; height: 0.4rem;
display: inline-block; display: inline-block;
border-radius: 1.5rem; border-radius: 1.5rem;
} }
@ -138,6 +198,7 @@
right: 0; right: 0;
} }
.interactive-box { .interactive-box {
user-select: none;
position: absolute; position: absolute;
width: 34vw; width: 34vw;
top: 70vh; top: 70vh;

View File

@ -41,7 +41,6 @@
let audioId = uuidv1(); let audioId = uuidv1();
localforage.setItem(audioId + '-file', file, function (err) { localforage.setItem(audioId + '-file', file, function (err) {
if (err) { if (err) {
console.error(err);
failed.update((prev) => [...prev, file]); failed.update((prev) => [...prev, file]);
} else { } else {
if (file.cover === 'N/A') { if (file.cover === 'N/A') {
@ -57,7 +56,6 @@
let blob = fetch(file.pic).then((r) => { let blob = fetch(file.pic).then((r) => {
localforage.setItem(audioId + '-cover', r.blob(), function (err) { localforage.setItem(audioId + '-cover', r.blob(), function (err) {
if (err) { if (err) {
console.error(err);
failed.update((prev) => [...prev, file]); failed.update((prev) => [...prev, file]);
} else { } else {
success.update((prev) => [...prev, file]); success.update((prev) => [...prev, file]);

View File

@ -10,6 +10,7 @@
const audioId = $page.params.id; const audioId = $page.params.id;
let audioPlayer: HTMLAudioElement; let audioPlayer: HTMLAudioElement;
let volume = 1;
let name = ''; let name = '';
let singer = ''; let singer = '';
let duration = 0; let duration = 0;
@ -91,7 +92,6 @@
$: { $: {
if (!launched) { if (!launched) {
console.log('launch?');
const requirements = ['name', 'file', 'cover']; const requirements = ['name', 'file', 'cover'];
let flag = true; let flag = true;
for (const r of requirements) { for (const r of requirements) {
@ -99,32 +99,33 @@
flag = false; flag = false;
} }
} }
console.log(prepared, flag);
if (flag) { if (flag) {
launched = true; launched = true;
console.log('launch!');
setMediaSession(); setMediaSession();
audioPlayer.play(); audioPlayer.play();
} }
} }
} }
function adjustProgress(progress: number) {
if (audioPlayer) {
audioPlayer.currentTime = duration * progress;
currentProgress = duration * progress;
}
}
$: { $: {
clearInterval(mainInterval); clearInterval(mainInterval);
mainInterval = setInterval(() => { mainInterval = setInterval(() => {
if (audioPlayer !== null && audioPlayer.currentTime !== undefined) { if (audioPlayer !== null && audioPlayer.currentTime !== undefined) {
currentProgress = audioPlayer.currentTime; currentProgress = audioPlayer.currentTime;
} }
}, 500); }, 250);
} }
$: { $: {
if (audioPlayer) { if (audioPlayer) {
paused = audioPlayer.paused; paused = audioPlayer.paused;
if (audioPlayer.ended) {
paused = true;
audioPlayer.pause();
}
} }
} }
readDB(); readDB();
@ -139,5 +140,14 @@
progress={currentProgress} progress={currentProgress}
clickPlay={playAudio} clickPlay={playAudio}
{paused} {paused}
{adjustProgress}
/> />
<audio bind:this={audioPlayer} controls style="display: none"></audio> <audio
bind:this={audioPlayer}
controls
style="display: none"
on:ended={() => {
paused = true;
audioPlayer.pause();
}}
></audio>