55 lines
1.8 KiB
Svelte
55 lines
1.8 KiB
Svelte
<script lang="ts">
|
|
import { getAssetUrlKey } from '$utils/api'
|
|
|
|
export let src: string = undefined
|
|
export let id: string = undefined
|
|
export let sizeKey: string = undefined
|
|
export let sizes: Sizes = undefined
|
|
export let width: number = sizes?.medium?.width
|
|
export let height: number = sizes?.medium?.height
|
|
export let ratio: number = undefined
|
|
export let alt: string
|
|
export let lazy = true
|
|
export let decoding: 'auto' | 'sync' | 'async' = 'auto'
|
|
|
|
interface Sizes {
|
|
small?: { width?: number; height?: number }
|
|
medium?: { width?: number; height?: number }
|
|
large?: { width?: number; height?: number }
|
|
}
|
|
|
|
const setHeightFromRatio = (w: number, r: number = ratio) => Math.round(w / r)
|
|
|
|
if (ratio && !height) {
|
|
height = setHeightFromRatio(width)
|
|
if (sizes) {
|
|
for (const [key, value] of Object.entries(sizes)) {
|
|
sizes[key].height = setHeightFromRatio(value.width)
|
|
}
|
|
}
|
|
}
|
|
|
|
$: imgWidth = sizes?.small?.width || width
|
|
$: imgHeight = sizes?.small?.height || height
|
|
$: imgSrc = id ? getAssetUrlKey(id, `${sizeKey}-small`) : src
|
|
$: srcSet = sizes
|
|
? [
|
|
`${getAssetUrlKey(id, `${sizeKey}-small`)} 345w`,
|
|
sizes.medium && `${getAssetUrlKey(id, `${sizeKey}-medium`)} 768w`,
|
|
sizes.large && `${getAssetUrlKey(id, `${sizeKey}-large`)} 1280w`,
|
|
]
|
|
: [getAssetUrlKey(id, sizeKey)]
|
|
</script>
|
|
|
|
<picture class={$$props.class}>
|
|
<img
|
|
src={imgSrc}
|
|
sizes={sizes ? '(min-width: 1200px) 864px, (min-width: 992px) 708px, (min-width: 768px) 540px, 100%' : undefined}
|
|
srcset={srcSet.join(', ')}
|
|
width={imgWidth}
|
|
height={imgHeight}
|
|
{alt}
|
|
loading={lazy ? 'lazy' : undefined}
|
|
{decoding}
|
|
/>
|
|
</picture> |