🔥 Implement sizes with Image component and webp loading with source
This commit is contained in:
@@ -1,25 +1,69 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getAssetUrl } from '$utils/helpers'
|
import { getAssetUrl } from '$utils/helpers'
|
||||||
|
|
||||||
export let id: string
|
export let src: string = undefined
|
||||||
export let alt: string
|
export let id: string = undefined
|
||||||
export let width: number
|
export let sizes: Sizes = undefined
|
||||||
export let height: number
|
export let width: number = sizes && sizes.medium && sizes.medium.width
|
||||||
export let quality: number = 90
|
export let height: number = sizes && sizes.medium && sizes.medium.height
|
||||||
export let sizes: any = {}
|
export let ratio: number = undefined
|
||||||
|
export let quality: number = 80
|
||||||
export let fit: string = 'inside'
|
export let fit: string = 'inside'
|
||||||
export let format: string = 'jpg'
|
export let alt: string
|
||||||
export let lazy: boolean = true
|
export let lazy: boolean = true
|
||||||
|
|
||||||
// TODO:
|
interface Sizes {
|
||||||
// - sizes
|
small?: { width?: number, height?: number }
|
||||||
// -- width
|
medium?: { width?: number, height?: number }
|
||||||
// -- height
|
large?: { width?: number, height?: number }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define height from origin ratio if not defined
|
||||||
|
*/
|
||||||
|
const setHeightFromRatio = (w: number, r: number = ratio) => {
|
||||||
|
return Math.round(w / r)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ratio && !height) {
|
||||||
|
// Set height from width using ratio
|
||||||
|
height = setHeightFromRatio(width)
|
||||||
|
|
||||||
|
// Add height to all sizes
|
||||||
|
if (sizes) {
|
||||||
|
Object.entries(sizes).forEach(size => {
|
||||||
|
const [key, value]: [string, { width?: number, height?: number }] = size
|
||||||
|
sizes[key].height = setHeightFromRatio(value.width)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Image attributes
|
||||||
|
*/
|
||||||
|
const imgWidth: number = sizes && sizes.small ? sizes.small.width : width
|
||||||
|
const imgHeight: number = sizes && sizes.small ? sizes.small.height : height
|
||||||
|
const imgSrc = id ? getAssetUrl(id, imgWidth, imgHeight, quality, fit, 'jpg') : src ? src : null
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<picture class={$$props.class}>
|
<picture class={$$props.class ? $$props.class : ''}>
|
||||||
|
<source
|
||||||
|
type="image/webp"
|
||||||
|
srcset="
|
||||||
|
{getAssetUrl(id, imgWidth, imgHeight, quality, fit, 'webp')} 345w,
|
||||||
|
{sizes && sizes.medium ? `${getAssetUrl(id, sizes.medium.width, sizes.medium.height, quality, fit, 'webp')} 768w,` : ''}
|
||||||
|
{sizes && sizes.large ? `${getAssetUrl(id, sizes.large.width, sizes.large.height, quality, fit, 'webp')} 1280w,` : ''}
|
||||||
|
"
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
src={getAssetUrl(id, width, height, quality, fit, format)}
|
src={imgSrc}
|
||||||
|
sizes="(min-width: 1200px) 864px, (min-width: 992px) 708px, (min-width: 768px) 540px, 100%"
|
||||||
|
srcset="
|
||||||
|
{getAssetUrl(id, imgWidth, imgHeight, quality, fit)} 300w,
|
||||||
|
{sizes && sizes.medium ? `${getAssetUrl(id, sizes.medium.width, sizes.medium.height, quality, fit)} 768w,` : ''}
|
||||||
|
{sizes && sizes.large ? `${getAssetUrl(id, sizes.large.width, sizes.large.height, quality, fit)} 1280w,` : ''}
|
||||||
|
"
|
||||||
width={width}
|
width={width}
|
||||||
height={height}
|
height={height}
|
||||||
alt={alt}
|
alt={alt}
|
||||||
|
|||||||
@@ -6,5 +6,14 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="photo-card">
|
<div class="photo-card">
|
||||||
<Image id={id} alt={alt} width={864} height={576} />
|
<Image
|
||||||
|
id={id}
|
||||||
|
sizes={{
|
||||||
|
small: { width: 224 },
|
||||||
|
medium: { width: 464 },
|
||||||
|
large: { width: 864 },
|
||||||
|
}}
|
||||||
|
ratio={1.5}
|
||||||
|
alt={alt}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -253,7 +253,16 @@
|
|||||||
{#each photos as { image, slug, location }}
|
{#each photos as { image, slug, location }}
|
||||||
<div class="photo shadow-photo">
|
<div class="photo shadow-photo">
|
||||||
<a href="/{location.country.slug}/{location.slug}/{slug}">
|
<a href="/{location.country.slug}/{location.slug}/{slug}">
|
||||||
<Image id={image.id} width={1200} height={800} alt={image.title} />
|
<Image
|
||||||
|
id={image.id}
|
||||||
|
sizes={{
|
||||||
|
small: { width: 500 },
|
||||||
|
medium: { width: 900 },
|
||||||
|
large: { width: 1440 },
|
||||||
|
}}
|
||||||
|
ratio={1.5}
|
||||||
|
alt={image.title}
|
||||||
|
/>
|
||||||
<PostCard />
|
<PostCard />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user