UNPKG

gatsby-background-image

Version:

Lazy-loading React background-image component with optional support for the blur-up effect.

153 lines (121 loc) 5.2 kB
"use strict"; exports.__esModule = true; exports.switchImageSettings = exports.noscriptImg = exports.createPictureRef = exports.activateCacheForImage = exports.inImageCache = void 0; var _HelperUtils = require("./HelperUtils"); var imageCache = {}; /** * Cache if we've seen an image before so we don't both with * lazy-loading & fading in on subsequent mounts. * * @param props * @return {*|boolean} */ var inImageCache = function inImageCache(props) { var convertedProps = (0, _HelperUtils.convertProps)(props); // Find src var src = convertedProps.fluid ? convertedProps.fluid.src : convertedProps.fixed ? convertedProps.fixed.src : null; return imageCache[src] || false; }; /** * Adds an Image to imageCache. * @param props */ exports.inImageCache = inImageCache; var activateCacheForImage = function activateCacheForImage(props) { var convertedProps = (0, _HelperUtils.convertProps)(props); // Find src var src = convertedProps.fluid ? convertedProps.fluid.src : convertedProps.fixed ? convertedProps.fixed.src : null; if (src) { imageCache[src] = true; } }; /** * Creates a picture element for the browser to decide which image to load. * * @param props * @param onLoad * @return {HTMLImageElement|null} */ exports.activateCacheForImage = activateCacheForImage; var createPictureRef = function createPictureRef(props, onLoad) { var convertedProps = (0, _HelperUtils.convertProps)(props); if (typeof window !== "undefined" && (typeof convertedProps.fluid !== "undefined" || typeof convertedProps.fixed !== "undefined")) { var imageData = props.fluid ? props.fluid : props.fixed; var img = new Image(); var pic = document.createElement('picture'); if (imageData.srcSetWebp) { var sourcesWebP = document.createElement('source'); sourcesWebP.type = "image/webp"; sourcesWebP.srcset = imageData.srcSetWebp; sourcesWebP.sizes = imageData.sizes; pic.appendChild(sourcesWebP); } pic.appendChild(img); img.onload = function () { return onLoad(); }; if (!img.complete && typeof convertedProps.onLoad === "function") { img.addEventListener('load', convertedProps.onLoad); } if (typeof convertedProps.onError === "function") { img.addEventListener('error', convertedProps.onError); } img.srcset = imageData.srcSet ? imageData.srcSet : ""; img.src = imageData.src ? imageData.src : ""; return img; } return null; }; /** * Create basic image for a noscript event. * * @param props * @return {string} */ exports.createPictureRef = createPictureRef; var noscriptImg = function noscriptImg(props) { // Check if prop exists before adding each attribute to the string output below to prevent // HTML validation issues caused by empty values like width="" and height="" var src = props.src ? "src=\"" + props.src + "\" " : "src=\"\" "; // required attribute var sizes = props.sizes ? "sizes=\"" + props.sizes + "\" " : ""; var srcSetWebp = props.srcSetWebp ? "<source type='image/webp' srcset=\"" + props.srcSetWebp + "\" " + sizes + "/>" : ""; var srcSet = props.srcSet ? "srcset=\"" + props.srcSet + "\" " : ""; var title = props.title ? "title=\"" + props.title + "\" " : ""; var alt = props.alt ? "alt=\"" + props.alt + "\" " : "alt=\"\" "; // required attribute var width = props.width ? "width=\"" + props.width + "\" " : ""; var height = props.height ? "height=\"" + props.height + "\" " : ""; var opacity = props.opacity ? props.opacity : "1"; var transitionDelay = props.transitionDelay ? props.transitionDelay : "0.5s"; return "<picture>" + srcSetWebp + "<img " + width + height + sizes + srcSet + src + alt + title + "style=\"position:absolute;top:0;left:0;z-index:-1;transition:opacity 0.5s;transition-delay:" + transitionDelay + ";opacity:" + opacity + ";width:100%;height:100%;object-fit:cover;object-position:center\"/></picture>"; }; /** * Compares the old states to the new and changes image settings accordingly. * * @param image * @param bgImage * @param imageRef * @param isVisible * @return {{noBase64: boolean, afterOpacity: number, bgColor: *, bgImage: *, nextImage: string}} */ exports.noscriptImg = noscriptImg; var switchImageSettings = function switchImageSettings(_ref) { var image = _ref.image, bgImage = _ref.bgImage, imageRef = _ref.imageRef, isVisible = _ref.isVisible; var noBase64 = !image.base64; // Set the backgroundImage according to images available. var nextImage = ""; if (image.tracedSVG) nextImage = "\"" + image.tracedSVG + "\""; if (image.base64 && !image.tracedSVG) nextImage = image.base64; if (isVisible) nextImage = imageRef && imageRef.currentSrc || image.src; // Switch bgImage & nextImage and opacity accordingly. var lastImage = bgImage; bgImage = bgImage === "" ? nextImage : ""; nextImage = nextImage === bgImage ? "" : nextImage; var afterOpacity = nextImage !== "" || noBase64 && isVisible ? 1 : 0; return { bgImage: bgImage, lastImage: lastImage, nextImage: nextImage, afterOpacity: afterOpacity, noBase64: noBase64 }; }; exports.switchImageSettings = switchImageSettings;