diff --git a/packages/xrias/package.json b/packages/xrias/package.json index 023437e..d09f5c2 100644 --- a/packages/xrias/package.json +++ b/packages/xrias/package.json @@ -1,6 +1,6 @@ { "name": "@ekwoka/x-rias", - "version": "1.2.1", + "version": "1.2.2", "description": "A simple Alpine Directive for use with Cloudinary Fetch API for handling Responsive Images", "author": { "name": "Eric Kwoka", diff --git a/packages/xrias/src/resizeObserver.ts b/packages/xrias/src/resizeObserver.ts index 0ff2535..18f3165 100644 --- a/packages/xrias/src/resizeObserver.ts +++ b/packages/xrias/src/resizeObserver.ts @@ -1,15 +1,15 @@ -const debounceObserver = ( - fn: (elements: Set, observer: ResizeObserver) => void, +const debounceObserver = ( + fn: (elements: Set, observer: ResizeObserver) => void, delay: number, ): ResizeObserverCallback => { - let timer: number; - const allElements = new Set(); + let timer: number | NodeJS.Timeout | null; + const allElements = new Set(); return function ( entries: ResizeObserverEntry[], observer: ResizeObserver, ): void { if (timer) clearTimeout(timer); - entries.forEach(({ target }) => allElements.add(target as HTMLElement)); + entries.forEach(({ target }) => allElements.add(target as T)); timer = setTimeout(() => { fn(allElements, observer); timer = null; @@ -17,18 +17,31 @@ const debounceObserver = ( }; }; -const observerCB = (els: Set) => { +const observerCB = (els: Set) => { els.forEach((el) => resize(el)); + els.clear(); }; -const resize = (el: HTMLElement) => { - let sizes = el.offsetWidth; - let parent = el.parentNode as HTMLElement; - while (sizes < 100 && parent) { - sizes = parent.offsetWidth; +const resize = (el: HTMLImageElement) => { + const setSize = (width: number) => + el.setAttribute('sizes', (width | 0) + 'px'); + let width = 0; + let height = 0; + let parent: HTMLElement | null = el; + while (width < 100 && parent) { + width = parent.offsetWidth; + height = parent.offsetHeight; parent = parent.parentNode as HTMLElement; } - el.setAttribute('sizes', sizes + 'px'); + const objectFit = getComputedStyle(el).objectFit; + if (objectFit !== 'cover') return setSize(width); + const imageRatio = + Number(el.getAttribute('width')) / Number(el.getAttribute('height')); + if (!imageRatio) return setSize(width); + const displayedRatio = width / height; + if (displayedRatio >= imageRatio + 0.1) return setSize(width); + const newWidth = height * imageRatio; + setSize(newWidth); }; export const observer = new ResizeObserver(debounceObserver(observerCB, 800)); diff --git a/size.json b/size.json index a856e90..cd60b73 100644 --- a/size.json +++ b/size.json @@ -11,12 +11,12 @@ }, "xrias": { "minified": { - "pretty": "1.67 kB", - "raw": 1669 + "pretty": "1.86 kB", + "raw": 1856 }, "brotli": { - "pretty": "818 B", - "raw": 818 + "pretty": "909 B", + "raw": 909 } }, "xrouter": {