Files
f.bosin.ch/src/lib/components/Photo.svelte
2023-08-24 23:11:50 +02:00

150 lines
3.1 KiB
Svelte

<script>
import { strf } from "$lib/data/language";
import { getFileName } from "$lib/util/links";
import Icon from "./Icon.svelte";
/**
* The source of the image.
* @type {string}
*/
export let src;
/** @type {Album} */
export let album;
/**
* The item.
* @type {Item}
*/
export let item;
/**
* Whether the image is the first one in the viewport.
* @type {boolean}
*/
export let lazy = false;
/**
* The click handler for the image.
* @param {MouseEvent} event
*/
async function clickHandler(event) {
event.preventDefault();
console.log('click', event);
}
/**
* The right click handler for the image.
* @param {MouseEvent} event
*/
async function rightClickHandler(event) {
event.preventDefault();
console.log('right click', event);
}
$: filename = getFileName(item.item);
$: alt = (item.title ? $strf(item.title) : null) || (item.description ? $strf(item.description) : null) || filename;
$: title = item.title ? $strf(item.title) : filename;
$: author = item.authors ? (
Array.isArray(item.authors) ?
item.authors[0]:
typeof item.authors === 'string' ?
item.authors:
"unknown author"):
album.authors ? (
Array.isArray(album.authors) ?
album.authors[0]:
typeof album.authors === 'string' ?
album.authors:
"unknown author"):
"Luca Bosin";
</script>
<li>
<figure style="--image: url('{src}/t/3')">
<picture>
<source media="(min-width: 2560px)" srcset="{src}/t/l" />
<source media="(min-width: 1600px)" srcset="{src}/t/m" />
<img src="{src}/t" {alt} loading={lazy ? 'lazy' : 'eager'} />
</picture>
<figcaption>
<b>{title}</b>
<cite>{author}</cite>
</figcaption>
</figure>
<a href={src} on:click={clickHandler} on:contextmenu={rightClickHandler}>
<Icon class="icon" mdi="arrow-expand" size={2.25}/>
</a>
</li>
<style>
li {
position: relative;
height: fit-content;
border-radius: 10px;
overflow: hidden;
min-width: 30vw;
}
figure {
width: 30vw;
height: 20vw;
background-color: rgba(0,0,0,.25);
background-image: var(--image);
background-position: center;
background-size: cover;
}
img {
width: 30vw;
height: 20vw;
object-fit: contain;
}
figcaption {
display: grid;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: 1em;
opacity: 0;
transition: opacity .5s;
z-index: 1;
gap: .25em;
pointer-events: none;
}
b {
font-size: 1.25em;
}
cite {
font-size: .75em;
font-weight: normal;
font-style: normal;
opacity: .8;
}
a {
display: grid;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.5);
color: inherit;
text-decoration: none;
opacity: 0;
transition: opacity .5s;
justify-content: center;
align-content: center;
}
li:hover :is(figcaption, a) {
opacity: 1;
}
</style>