UNPKG

use-element-fit

Version:

useElementFit is a React hook that allows you to measure and element's based on certain restraints, similar to object-fit in CSS.

107 lines (100 loc) 4.29 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('use-resize-observer')) : typeof define === 'function' && define.amd ? define(['exports', 'react', 'use-resize-observer'], factory) : (global = global || self, factory(global.useElementFit = {}, global.react, global.useResizeObserver)); }(this, function (exports, react, useResizeObserver) { 'use strict'; useResizeObserver = useResizeObserver && useResizeObserver.hasOwnProperty('default') ? useResizeObserver['default'] : useResizeObserver; var ScaleMode; (function (ScaleMode) { ScaleMode["CONTAIN"] = "contain"; ScaleMode["COVER"] = "cover"; ScaleMode["ALIGN_ONLY"] = "align-only"; })(ScaleMode || (ScaleMode = {})); var ScaleMode$1 = ScaleMode; const resize = (elementWidth, elementHeight, containerWidth, containerHeight, scaleMode, alignmentX = 0.5, alignmentY = 0.5, maxWidth, maxHeight) => { let targetWidth = 0; let targetHeight = 0; let boundRatioX = 0; let boundRatioY = 0; let scale = 1; // get needed scale to fit in bounds with cover if (scaleMode === ScaleMode$1.CONTAIN || scaleMode === ScaleMode$1.COVER) { boundRatioX = containerWidth / elementWidth; boundRatioY = containerHeight / elementHeight; } // get scale for bounds container switch (scaleMode) { case ScaleMode$1.CONTAIN: scale = boundRatioX < boundRatioY ? boundRatioX : boundRatioY; break; case ScaleMode$1.COVER: scale = boundRatioX > boundRatioY ? boundRatioX : boundRatioY; break; case ScaleMode$1.ALIGN_ONLY: targetWidth = elementWidth; targetHeight = elementHeight; break; } if (scaleMode === ScaleMode$1.CONTAIN || scaleMode === ScaleMode$1.COVER) { // get needed scale to fit in max with contain if (maxWidth || maxHeight) { let scaleMaxRatioX = scale; let scaleMaxRatioY = scale; if (maxWidth) { scaleMaxRatioX = maxWidth / elementWidth; } if (maxHeight) { scaleMaxRatioY = maxHeight / elementHeight; } const scaleMax = scaleMaxRatioX < scaleMaxRatioY ? scaleMaxRatioX : scaleMaxRatioY; scale = Math.min(scale, scaleMax); } // do the actual scale targetWidth = elementWidth * scale; targetHeight = elementHeight * scale; } return { width: Math.round(targetWidth), height: Math.round(targetHeight), x: Math.round((containerWidth - targetWidth) * alignmentX), y: Math.round((containerHeight - targetHeight) * alignmentY), }; }; const useElementFit = (width, height, scaleMode = ScaleMode$1.CONTAIN, alignmentX = 0.5, alignmentY = 0.5, maxWidth, maxHeight) => { const [ref, containerWidth, containerHeight] = useResizeObserver(); const [fitWidth, setFitWidth] = react.useState(1); const [fitHeight, setFitHeight] = react.useState(1); const [fitX, setFitX] = react.useState(1); const [fitY, setFitY] = react.useState(1); react.useEffect(() => { const { width: newWidth, height: newHeight, x, y } = resize(width, height, containerWidth, containerHeight, scaleMode, alignmentX, alignmentY, maxWidth, maxHeight); setFitWidth(newWidth); setFitHeight(newHeight); setFitX(x); setFitY(y); }, [ containerWidth, containerHeight, width, height, containerWidth, containerHeight, scaleMode, alignmentX, alignmentY, maxWidth, maxHeight, ]); return { ref, width: fitWidth, height: fitHeight, x: fitX, y: fitY, }; }; exports.ScaleMode = ScaleMode$1; exports.useElementFit = useElementFit; Object.defineProperty(exports, '__esModule', { value: true }); })); //# sourceMappingURL=index.js.map