UNPKG

responsive-image-utils

Version:

Utility functions to make it easier to work with auto generated responsive images for better performance optimised images.

161 lines (151 loc) 6.46 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = global || self, factory(global.responsiveImageUtils = {})); }(this, function (exports) { 'use strict'; /** Default media query values */ var MediaQueriesDefault = { s: 640, m: 1024, l: 1280, xl: 1920, xxl: 2560, }; /** * Use this to auto calculate various image sizes based on your media query breakpoints and fluid image sizes using VW * * @param sizes - key/value pair of media query and image size {s: '50vw', l: '25vw', xl: '500px'} * @param mediaQueries - Optional. key/value pair of media query breakpoints. Defaults to MediaQueriesDefault * @returns Number array of generated image sizes * */ function getSrcsetSizes(sizes, mediaQueries) { if (mediaQueries === void 0) { mediaQueries = MediaQueriesDefault; } var prevSize = '100vw'; var getSizePerMediaQuery = Object.keys(mediaQueries).map(function (key) { var _a; var currentSize = sizes[key] ? sizes[key] : prevSize; prevSize = currentSize; return _a = {}, _a[key] = currentSize, _a; }); var srcSets = getSizePerMediaQuery.map(function (sizeObj) { var key = Object.keys(sizeObj)[0]; var sizeValue = sizeObj[key]; var unit = sizeValue.slice(-2); var mediaQuery = parseInt(sizeValue.replace(unit, ''), 10); if (unit !== 'px' && unit !== 'vw') { throw new Error(unit + " unit is not supported. Only supports px & vw"); } return unit === 'px' ? mediaQuery : Math.round((mediaQueries[key] * mediaQuery) / 100); }); return Array.from(new Set(srcSets)).sort(function (a, b) { return a - b; }); } /** * Use this to generate retina sizes for your sizes * * @param sizesArr - array of numbers [320, 640, 1024, 2048] * @param [multiplier] - number to multiply the images by, you can provide multiples getRetinaSizes(array, 2, 3, 4) * @returns Number array of generated image sizes * */ function getRetinaSizes(sizesArr) { var multiplier = []; for (var _i = 1; _i < arguments.length; _i++) { multiplier[_i - 1] = arguments[_i]; } var newSizes = multiplier .map(function (n) { return sizesArr.slice(0).map(function (size) { return size * n; }); }) .reduce(function (prev, curr) { return prev.concat(curr); }, sizesArr); return Array.from(new Set(newSizes)); } /** * Use this to limit the number of image sizes provided to the browser. * This will automatically choose every Nth image to ensure image sizes are not so close to each other * * @param max - the maximum number of sizes * @param sizesArr - array of numbers [320, 640, 1024, 2048] * @returns Number array of generated image sizes * */ function getMaxNumOfSizes(sizesArr, max) { if (max > sizesArr.length) { throw new Error('Max is greater than sizes length!'); } var ascSizes = sizesArr.sort(function (a, b) { return a - b; }); return Array(max) .fill(0) .map(function (n, i) { var index = ascSizes.length - i * Math.ceil(ascSizes.length / max); if (index < 1) { return i * Math.ceil(ascSizes.length / max) - ascSizes.length + 1; } return index; }) .map(function (n) { return ascSizes[n - 1]; }) .sort(function (a, b) { return a - b; }); } /** * Use this to combine your media queries and sizes to generate a string to populate your image tag * * @param sizes - key/value pair of media query and image size {s: '50vw', l: '25vw', xl: '500px'} * @param mediaQueries - Optional. key/value pair of media query breakpoints. Defaults to MediaQueriesDefault * @returns String array of generated string sizes * */ function getImgSizeStrings(sizes, mediaQueries) { if (mediaQueries === void 0) { mediaQueries = MediaQueriesDefault; } var mediaQueriesMinWidth = function () { var prevKey = ''; return Object.keys(mediaQueries) .map(function (key) { var _a; var currentMinWidth = mediaQueries[prevKey] ? mediaQueries[prevKey] + 1 : 0; prevKey = key; return _a = {}, _a[key] = currentMinWidth, _a; }) .reduce(function (prev, curr) { return Object.assign(prev, curr); }, {}); }; return Object.keys(sizes) .map(function (sizeKey) { if (mediaQueriesMinWidth()[sizeKey] === 0) { return sizes[sizeKey]; } return "(min-width:" + mediaQueriesMinWidth()[sizeKey] + "px) " + sizes[sizeKey]; }) .reverse(); } /** * You can use *getSizesWithInterval* which will take N results from the set * without the sizes being too close to each other. * For example, if you have the following sizes `[300, 320, 460, 480, 1024]`, * you might want to remove `300` & `460` since the 20px difference with the * next size up has marginal benefit over page weight * * @param sizesArr - array of numbers [320, 640, 1024, 2048] * @param interval - how much interval should each size have from each other * @returns Number array of generated image sizes * */ function getSizesWithInterval(sizesArr, interval) { return sizesArr .sort(function (a, b) { return b - a; }) .reduce(function (accumulator, current) { if (accumulator[accumulator.length - 1] - current < interval) { return accumulator; } return accumulator.concat([current]); }, []) .sort(function (a, b) { return a - b; }); } exports.getMaxNumOfSizes = getMaxNumOfSizes; exports.getRetinaSizes = getRetinaSizes; exports.getImgSizeStrings = getImgSizeStrings; exports.getSrcsetSizes = getSrcsetSizes; exports.getSizesWithInterval = getSizesWithInterval; Object.defineProperty(exports, '__esModule', { value: true }); })); //# sourceMappingURL=responsive-image-utils.umd.js.map