Start implementing lightbox

Moving between images works, and we preload one on either side of the
current index. There's also the beginnings of some slide animations
which is my next job.
ご主人様
not manx 4 years ago
parent c471107b73
commit cfc51f04c3
Signed by: C-xC-c
GPG Key ID: F52ED472284EF2F4

@ -1,5 +1,39 @@
<script>
let world = 'qt';
import { onMount } from 'svelte';
import Lightbox from './lightbox.svelte';
let file_list;
let open;
let thumb_list = [];
const url = {
root: 'https://wg.flanchan.moe/cake/',
thumb: 'thumb/',
files: 'filelist.txt'
};
onMount(async () => {
file_list = await fetch(url.root + url.files)
.then(resp => resp.text())
.then(data => data.split('\n'));
// Loop backwards efficiently
for (let i = file_list.length - 2; i >= 0; i--) {
const file = file_list[i];
thumb_list.push(file.substr(0, file.lastIndexOf('.')) + '.jpg');
}
});
function open_lightbox(i) {
open = null;
open = i;
}
</script>
<h1 class="text-center text-4xl font-bold">Hey {world}</h1>
{#if file_list}
<section>
{#each thumb_list as thumb, i}
<img on:click={() => open_lightbox(i)} src="{url.root}{url.thumb}{thumb}" />
{/each}
</section>
{/if}
<Lightbox open={open} url={url} images={file_list} />

@ -0,0 +1,108 @@
<script>
import { onMount } from 'svelte';
export let open;
export let url;
export let images;
let slide_classes = '';
let class_list = 'lightbox';
let should_open = true;
$: image = open !== null && open >= 0 ? set_images() : '';
$: is_open(open);
function is_open(i) {
if (should_open && i !== null && i >= 0) {
class_list += ' open'
should_open = false;
}
}
function close(e) {
if (e.target.tagName === 'IMG')
return;
if (!should_open) {
open = null;
should_open = true;
class_list = 'lightbox';
slide_classes = '';
}
}
function set_images() {
const img = images.length - (open + 2)
return [
url.root + images[img - 1],
url.root + images[img],
url.root + images[img + 1]
]
}
function handle_keys(e) {
if(should_open)
return;
switch(e.key) {
case 'ArrowRight':
open = open === (images.length - 2) ? 0 : open + 1;
break;
case 'ArrowLeft':
open = open === 0 ? images.length - 2 : open - 1;
slide_classes = 'slide-in-left';
break;
}
}
onMount(() => {
let lightbox = document.getElementById('lightbox');
lightbox.addEventListener('animationend', () => slide_classes = '');
});
</script>
<style>
.slide-in-left {
animation: slide-in-left .3s ease;
}
@keyframes slide-in-left {
from {
opacity: 0;
transform: translate3d(-60%, 0, 0);
}
to {
visibility: visible;
transform: translate3d( 0, 0, 0);
opacity: 1;
}
}
.lightbox {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
opacity: 1;
transition: opacity 1s;
display: flex;
justify-content: center;
align-items: center;
z-index: -1;
}
.open {
background-color: rgba(0,0,0,0.7);
z-index: 0;
}
</style>
<svelte:window on:keydown={handle_keys} />
<div id="lightbox" class="{class_list} {slide_classes}" on:click={close}>
<img class=" hidden" rel="preload" src="{image[0]}" />
<img class="object-contain max-w-full max-h-full" src="{image[1]}" />
<img class="hidden" rel="preload" src="{image[2]}" />
</div>
Loading…
Cancel
Save