UNPKG

@nichoth/image

Version:
74 lines 2.99 kB
import { Cloudinary } from '@cloudinary/url-gen'; import { scale } from '@cloudinary/url-gen/actions/resize'; import { h } from 'preact'; import { useRef, useEffect } from 'preact/hooks'; import { CloudinarySrcset } from './srcset.js'; /** * This is a factory function that returns an object like { Image, BlurredImage }, * where `Image` and `BlurredImage` are preact components * @param config {{ cloudName:string }} The cloudName for Cloudinary * @returns { { Image:FunctionComponent } } */ export const CloudinaryImage = function (config) { const { cloudName } = config; const cld = new Cloudinary({ cloud: { cloudName }, url: { secure: true } }); const { defaultSrcset, getSrcset } = CloudinarySrcset(cld); const Image = function (props) { const { decoding, filename, alt, loading, fetchpriority, className, srcset, sizes } = props; // @ts-ignore -- related to `fetchpriority` return h('img', { class: props.class || className, alt, srcset: (srcset ? getSrcset(filename, srcset).join(', ') : defaultSrcset(filename)), sizes: (sizes ? sizes.join(', ') : '100vw'), src: (cld.image(filename) .format('auto') .toURL()), loading: loading || 'lazy', decoding: decoding || 'auto', fetchpriority: fetchpriority || 'low' }); }; const BlurredImage = function (props) { const { maxWidth, blurPlaceholder, filename, className, sizes, srcset } = props; const placeholder = useRef(null); useEffect(() => { if (!placeholder.current) return; // also start downloading the real image const imgLarge = new window.Image(); const sources = (srcset ? getSrcset(filename, srcset).join(', ') : defaultSrcset(filename)); imgLarge.onload = () => imgLarge.classList.add('loaded'); imgLarge.setAttribute('sizes', sizes ? sizes.join(', ') : '100vw'); // srcset="elva-fairy-480w.jpg 480w, elva-fairy-800w.jpg 800w" imgLarge.setAttribute('srcset', sources); imgLarge.classList.add('sharp'); imgLarge.src = (cld.image(filename) .format('auto') .quality('auto') .resize(scale().width(maxWidth)) .toURL()); placeholder.current.appendChild(imgLarge); }, [placeholder.current]); const _class = props.class || className; return h('div', { class: 'placeholder' + (_class ? ` ${_class}` : ''), ref: placeholder }, [ h('img', { class: 'blurry loaded', src: blurPlaceholder }) ]); }; return { Image, BlurredImage }; }; export default CloudinaryImage; //# sourceMappingURL=preact.js.map