150 lines
3.1 KiB
Svelte
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>
|