🔥 Implement sizes with Image component and webp loading with source

This commit is contained in:
2021-10-13 23:33:07 +02:00
parent c45136beb0
commit 2ed411a94e
3 changed files with 77 additions and 15 deletions

View File

@@ -1,25 +1,69 @@
<script lang="ts">
import { getAssetUrl } from '$utils/helpers'
export let id: string
export let alt: string
export let width: number
export let height: number
export let quality: number = 90
export let sizes: any = {}
export let src: string = undefined
export let id: string = undefined
export let sizes: Sizes = undefined
export let width: number = sizes && sizes.medium && sizes.medium.width
export let height: number = sizes && sizes.medium && sizes.medium.height
export let ratio: number = undefined
export let quality: number = 80
export let fit: string = 'inside'
export let format: string = 'jpg'
export let alt: string
export let lazy: boolean = true
// TODO:
// - sizes
// -- width
// -- height
interface Sizes {
small?: { width?: number, height?: number }
medium?: { width?: number, height?: number }
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>
<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
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}
height={height}
alt={alt}