Source: media/utils/ImageTools.js

export { ImageTools }

/**
 * Static class with image related utilities.
 * @author ckraemme <ckraemme@awi.de>
 */
class ImageTools {
    /**
     * Select the matching resolution for a given width from an image srcset attribute containing width descriptors.
     * Reproduces the behavior of selecting an image with the srcset attribute.
     * @param {string} srcset - Srcset, i.e., "https://.../image1.jpg 720w, https://.../image2.jpg 1920w, https://.../image3.jpg 3840w".
     * @param {string|Number} width - Width in pixel i.e., "1800".
     * @returns {Array} List containing matching url and descriptor, i.e., ["https://.../image2.jpg", "1920w"].
     */
    static srcsetSelector(srcset, width) {

        var srcsetInfo = srcset.split(/,(?=\s|[a-zA-Z])/).map((item) => {
            const [url, descriptor] = item.trim().split(/\s+/);
            return [url, descriptor]
        });

        var naturalSort = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' });
        const index = 1;
        var numericDescriptor = srcsetInfo.map(item => item[index]);
        numericDescriptor.sort(naturalSort.compare);

        srcsetInfo.sort(function (firstElement, secondElement) {
            return numericDescriptor.indexOf(firstElement[index]) - numericDescriptor.indexOf(secondElement[index]);
        });

        let srcsetMatch = srcsetInfo[srcsetInfo.length - 1];
        for (let i = 0; i < numericDescriptor.length; i++) {
            if (parseInt(width) <= parseInt(numericDescriptor[i])) {
                srcsetMatch = srcsetInfo[i];
                break;
            }
        }
        return srcsetMatch
    }

    /**
     * Creates a monochrome image and return its data URL.
     * Note: const img = new Image(width, height);
     *       img.src = createImageDataUrl(width, height, color);
     * @param {number} width - Image width.
     * @param {number} height - Image height.
     * @param {string} color - Image color, e.g., "#0f1234" or "rgba(0,0,0,0)".
     */
    static createImageDataUrl(width, height, color) {
        const canvas = document.createElement('canvas');
        canvas.width = width;
        canvas.height = height;

        const ctx = canvas.getContext('2d');
        ctx.fillStyle = color;
        ctx.fillRect(0, 0, width, height);

        return canvas.toDataURL()
    }


    /**
     * Apply browser dependent srcset restrictions that cause bad performance in the pswp lightbox.
     * @param {string} src - Image url.
     * @param {string} srcset - Image srcset attribute with width descriptor.
     * @returns {Array} [src, srcset]
     */
    static improveLightboxPerformance(src, srcset) {
        if (srcset) {
            const isChromium = !!window.chrome;
            if (!isChromium) {
                const maxWidth = 100000;
                let imageSrc;
                [imageSrc,] = ImageTools.srcsetSelector(srcset, maxWidth);
                const imageFormat = imageSrc.split('.').pop();
                const isWebp = imageFormat.toLowerCase() == 'webp';
                if (isWebp) {
                    src = imageSrc;
                    srcset = null;
                }
            }
        }
        return [src, srcset]
    }
}