UNPKG

plaiceholder

Version:

Beautiful image placeholders, without the hassle.

297 lines (263 loc) 9.08 kB
import sharp from 'sharp'; function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } var _excluded = ["a"], _excluded2 = ["autoOrient", "size", "format", "brightness", "saturation", "removeAlpha"], _excluded3 = ["width", "height"]; /* Utils =========================================== */ var arrayChunk = function arrayChunk(arr, size) { return arr.length > size ? [arr.slice(0, size)].concat(arrayChunk(arr.slice(size), size)) : [arr]; }; var toRGBAString = function toRGBAString(_ref) { var r = _ref.r, g = _ref.g, b = _ref.b, a = _ref.a; if (typeof a === "undefined") return "rgb(" + [r, g, b].join(",") + ")"; return "rgba(" + [r, g, b, a].join(",") + ")"; }; var getPixels = function getPixels(_ref2) { var _ref3; var data = _ref2.data, info = _ref2.info; var channels = info.channels, width = info.width; var rawBuffer = (_ref3 = []).concat.apply(_ref3, data); var allPixels = arrayChunk(rawBuffer, channels); var rows = arrayChunk(allPixels, width); var pixels = rows.map(function (row) { return row.map(function (pixel) { var r = pixel[0], g = pixel[1], b = pixel[2], a = pixel[3]; return _extends({ r: r, g: g, b: b }, typeof a === "undefined" ? {} : { a: Math.round(a / 255 * 1000) / 1000 }); }); }); return pixels; }; var getCSS = function getCSS(_ref4) { var pixels = _ref4.pixels, info = _ref4.info; var linearGradients = pixels.map(function (row) { var rowPixels = row.map(function (pixel) { return toRGBAString(pixel); }); var gradient = rowPixels.map(function (pixel, i) { var start = i === 0 ? "" : " " + i / rowPixels.length * 100 + "%"; var end = i === rowPixels.length ? "" : " " + (i + 1) / rowPixels.length * 100 + "%"; return "" + pixel + start + end; }).join(","); return "linear-gradient(90deg, " + gradient + ")"; }); if (linearGradients.length !== info.height) { console.error("Woops! Something went wrong here and caused the color height to differ from the source height."); } var backgroundPosition = linearGradients.map(function (_, i) { return i === 0 ? "0 0 " : "0 " + i / (linearGradients.length - 1) * 100 + "%"; }).join(","); var backgroundSize = "100% " + 100 / linearGradients.length + "%"; return { backgroundImage: linearGradients.join(","), backgroundPosition: backgroundPosition, backgroundSize: backgroundSize, backgroundRepeat: "no-repeat" }; }; var getSVG = function getSVG(_ref5) { var _ref7; var pixels = _ref5.pixels, info = _ref5.info; var chunkRects = pixels.map(function (row, y) { return row.map(function (_ref6, x) { var a = _ref6.a, rgb = _objectWithoutPropertiesLoose(_ref6, _excluded); var colorProps = typeof a !== "undefined" ? { fill: toRGBAString(rgb), "fill-opacity": a } : { fill: toRGBAString(rgb), "fill-opacity": 1 }; return ["rect", _extends({}, colorProps, { width: 1, height: 1, x: x, y: y })]; }); }); if (chunkRects.length !== info.height) { console.error("Woops! Something went wrong here and caused the color height to differ from the source height."); } var rects = (_ref7 = []).concat.apply(_ref7, chunkRects); return ["svg", { xmlns: "http://www.w3.org/2000/svg", width: "100%", height: "100%", shapeRendering: "crispEdges", preserveAspectRatio: "none", viewBox: "0 0 " + info.width + " " + info.height, style: { position: "absolute", top: "50%", left: "50%", transformOrigin: "top left", transform: "translate(-50%, -50%)", right: 0, bottom: 0 } }, rects]; }; var getPlaiceholder = function getPlaiceholder(src, _temp) { var _ref8 = _temp === void 0 ? {} : _temp, _ref8$autoOrient = _ref8.autoOrient, autoOrient = _ref8$autoOrient === void 0 ? false : _ref8$autoOrient, _ref8$size = _ref8.size, size = _ref8$size === void 0 ? 4 : _ref8$size, _ref8$format = _ref8.format, format = _ref8$format === void 0 ? ["png"] : _ref8$format, _ref8$brightness = _ref8.brightness, brightness = _ref8$brightness === void 0 ? 1 : _ref8$brightness, _ref8$saturation = _ref8.saturation, saturation = _ref8$saturation === void 0 ? 1.2 : _ref8$saturation, _ref8$removeAlpha = _ref8.removeAlpha, removeAlpha = _ref8$removeAlpha === void 0 ? false : _ref8$removeAlpha, options = _objectWithoutPropertiesLoose(_ref8, _excluded2); try { /* Optimize ---------------------------------- */ return Promise.resolve(sharp(src).metadata().then(function (_ref9) { var width = _ref9.width, height = _ref9.height, metadata = _objectWithoutPropertiesLoose(_ref9, _excluded3); if (!width || !height) { throw Error("Could not get required image metadata"); } return _extends({ width: width, height: height }, metadata); })).then(function (metadata) { var _sharp$resize; var sizeMin = 4; var sizeMax = 64; var isSizeValid = sizeMin <= size && size <= sizeMax; !isSizeValid && console.error(["Please enter a `size` value between", sizeMin, "and", sizeMax].join(" ")); // initial optimization var pipelineStage1 = (_sharp$resize = sharp(src).resize(size, size, { fit: "inside" })).toFormat.apply(_sharp$resize, format).modulate(_extends({ brightness: brightness, saturation: saturation }, options != null && options.hue ? { hue: options == null ? void 0 : options.hue } : {}, options != null && options.lightness ? { lightness: options == null ? void 0 : options.lightness } : {})); // alpha var pipelineStage2 = removeAlpha === false ? pipelineStage1 : pipelineStage1.removeAlpha(); // autoOrientation var pipelineStage3 = autoOrient === false ? pipelineStage2 : pipelineStage2.rotate(); var pipeline = pipelineStage3; /* Return ---------------------------------- */ return Promise.resolve(pipeline.clone().stats().then(function (_ref10) { var _ref10$dominant = _ref10.dominant, r = _ref10$dominant.r, g = _ref10$dominant.g, b = _ref10$dominant.b; return { r: r, g: g, b: b, hex: "#" + [r, g, b].map(function (x) { return x.toString(16).padStart(2, "0"); }).join("") }; })).then(function (color) { return Promise.resolve(pipeline.clone().normalise().toBuffer({ resolveWithObject: true }).then(function (_ref11) { var data = _ref11.data, info = _ref11.info; return "data:image/" + info.format + ";base64," + data.toString("base64"); })["catch"](function (err) { console.error("base64 generation failed", err); throw err; })).then(function (base64) { return Promise.resolve(pipeline.clone().raw().toBuffer({ resolveWithObject: true }).then(function (_ref12) { var data = _ref12.data, info = _ref12.info; var pixels = getPixels({ data: data, info: info }); var css = getCSS({ pixels: pixels, info: info }); var svg = getSVG({ pixels: pixels, info: info }); return { pixels: pixels, css: css, svg: svg }; })["catch"](function (err) { console.error("pixel generation failed", err); throw err; })).then(function (_ref13) { var pixels = _ref13.pixels, css = _ref13.css, svg = _ref13.svg; return { color: color, css: css, base64: base64, metadata: metadata, pixels: pixels, svg: svg }; }); }); }); }); } catch (e) { return Promise.reject(e); } }; export { getPlaiceholder }; //# sourceMappingURL=plaiceholder.esm.js.map