Add style for photos
This commit is contained in:
@ -1,39 +1,31 @@
|
||||
<script>
|
||||
import { getFileName } from '$lib/util/links';
|
||||
import { strf } from '$lib/data/language.js';
|
||||
import Photo from './Photo.svelte';
|
||||
|
||||
/** @type {Item[]} */
|
||||
export let items = [];
|
||||
/** @type {Album} */
|
||||
export let album;
|
||||
|
||||
/** @type {Item[]?} */
|
||||
export let items = null;
|
||||
|
||||
export let base = '';
|
||||
|
||||
export let layout = 'grid';
|
||||
</script>
|
||||
|
||||
<section class="gallery"
|
||||
class:gallery--grid={layout === 'grid'}>
|
||||
{#if layout === 'grid'}
|
||||
<ul>
|
||||
{#each items as item (item.item)}
|
||||
<!-- <Photo src={`${uriBase}&item=${item.item}`} alt={$strf(item.title)} /> -->
|
||||
<li>
|
||||
<h3>{item.item}</h3>
|
||||
<p>
|
||||
<b>Title:</b> {#if item.title}{$strf(item.title)}{:else}<i>no title</i>{/if}<br />
|
||||
<b>Description:</b> {#if item.description}{$strf(item.description)}{:else}<i>no description</i>{/if}<br />
|
||||
<b>Links:</b> <a href={`${base}${item.item}`}>Open</a> • <a href={`${base}${item.item}/download`}>Download</a><br />
|
||||
<b>Thumbnails:</b> <a href={`${base}${item.item}/t/s`}>Small</a> • <a href={`${base}${item.item}/t/m`}>Medium</a> • <a href={`${base}${item.item}/t/l`}>Large</a> • <a href={`${base}${item.item}/t/full`}>Full</a>
|
||||
</p>
|
||||
<Photo src={`${base}${item.item}`} alt={(item.title ? $strf(item.title) : null) || (item.description ? $strf(item.description) : null) || getFileName(item.item)} />
|
||||
</li>
|
||||
<section>
|
||||
<ul>
|
||||
{#each (items || album.items) as item (item.item)}
|
||||
<Photo src={`${base}${item.item}`} {album} {item} />
|
||||
{/each}
|
||||
</ul>
|
||||
{:else}
|
||||
<i>layout not available</i>
|
||||
{/if}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
gap: 1em;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
<section class="title">
|
||||
{#if back}
|
||||
<a href={back}>
|
||||
<Icon name="arrow-left" />
|
||||
<Icon mdi="arrow-left" />
|
||||
</a>
|
||||
{/if}
|
||||
<h1>{title}</h1>
|
||||
|
||||
@ -1,10 +1,33 @@
|
||||
<script>
|
||||
export let name = '';
|
||||
name;
|
||||
export let clazz = '';
|
||||
export { clazz as class };
|
||||
export let color = 'currentColor';
|
||||
|
||||
/** @type {string} */
|
||||
export let mdi;
|
||||
|
||||
/** @type {number | string} */
|
||||
export let size = 1;
|
||||
|
||||
let mdiOld = '';
|
||||
let path = '';
|
||||
|
||||
$: {
|
||||
loadIcon(mdi);
|
||||
}
|
||||
|
||||
$: width = size ? (typeof size === 'number' || !Number.isNaN(Number(size)) ? `${size}em` : size) : '1em';
|
||||
|
||||
/**
|
||||
* @param {string} mdi
|
||||
*/
|
||||
async function loadIcon(mdi) {
|
||||
if (mdi === mdiOld) return;
|
||||
path = (await import(`$lib/icons/${mdi}.js`)).default;
|
||||
//path = icon.path;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
<svg class={clazz} viewBox="0 0 24 24" style="width: {width}; height: {width}">
|
||||
<path fill={color} d={path} />
|
||||
</svg>
|
||||
|
||||
@ -1,21 +1,28 @@
|
||||
<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;
|
||||
|
||||
/**
|
||||
* Alternative text for the image. Used for accessibility.
|
||||
* @type {string | undefined}
|
||||
* The item.
|
||||
* @type {Item}
|
||||
*/
|
||||
export let alt = undefined;
|
||||
export let item;
|
||||
|
||||
/**
|
||||
* Whether the image is the first one in the viewport.
|
||||
* @type {boolean}
|
||||
*/
|
||||
export let firstViewport = false;
|
||||
export let lazy = false;
|
||||
|
||||
/**
|
||||
* The click handler for the image.
|
||||
@ -23,18 +30,120 @@
|
||||
*/
|
||||
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>
|
||||
|
||||
<a href={src} on:click={clickHandler}>
|
||||
<picture>
|
||||
<source media="(min-width: 850px)" srcset="{src}/t/l" />
|
||||
<source media="(min-width: 450px)" srcset="{src}/t/m" />
|
||||
<img src="{src}/t" {alt} loading={firstViewport ? 'eager' : 'lazy'} />
|
||||
</picture>
|
||||
</a>
|
||||
<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>
|
||||
|
||||
2
src/lib/icons/arrow-expand.js
Normal file
2
src/lib/icons/arrow-expand.js
Normal file
@ -0,0 +1,2 @@
|
||||
const path = 'M10,21V19H6.41L10.91,14.5L9.5,13.09L5,17.59V14H3V21H10M14.5,10.91L19,6.41V10H21V3H14V5H17.59L13.09,9.5L14.5,10.91Z';
|
||||
export default path;
|
||||
2
src/lib/icons/arrow-left.js
Normal file
2
src/lib/icons/arrow-left.js
Normal file
@ -0,0 +1,2 @@
|
||||
const path = 'M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z';
|
||||
export default path;
|
||||
@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import { str, strf } from '$lib/data/language.js';
|
||||
import { strf } from '$lib/data/language.js';
|
||||
|
||||
import Header from '$lib/components/Header.svelte';
|
||||
import Gallery from '$lib/components/Gallery.svelte';
|
||||
@ -17,4 +17,6 @@
|
||||
<b>Sorting Date:</b> {data.album.date}<br />
|
||||
<b>License:</b> {data.album.license}<br />
|
||||
</p>
|
||||
<Gallery items={data.album.items} base={`${data.base}/i/`} />
|
||||
<main>
|
||||
<Gallery album={data.album} base={`${data.base}/i/`} />
|
||||
</main>
|
||||
|
||||
@ -20,12 +20,12 @@ export async function GET({ params }) {
|
||||
} else if (params.width === 'l') {
|
||||
width = 1200;
|
||||
} else if (!Number.isNaN(Number(params.width))) {
|
||||
width = Number(width);
|
||||
width = Number(params.width);
|
||||
}
|
||||
}
|
||||
thumbnail = thumbnail || await sharp(content).resize(width).webp({ quality: 90 }).toBuffer();
|
||||
} catch (err) {
|
||||
console.error(`${err.stack}`.replaceAll('/home/sveltekit', '.'));
|
||||
console.error(`${/** @type {Error} */(err).stack}`.replaceAll('/home/sveltekit', '.'));
|
||||
throw error(500, 'Error getting thumbnail');
|
||||
}
|
||||
return new Response(thumbnail, {
|
||||
|
||||
Reference in New Issue
Block a user