react-inner-image-zoom
Version:
A React component for magnifying an image within its parent container 🔎
278 lines (277 loc) • 15.2 kB
JavaScript
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _Image = _interopRequireDefault(require("./components/Image"));
var _ZoomImage = _interopRequireDefault(require("./components/ZoomImage"));
var _FullscreenPortal = _interopRequireDefault(require("./components/FullscreenPortal"));
var _images = require("inner-image-zoom/src/utils/images");
var _events = require("inner-image-zoom/src/utils/events");
var _this = void 0;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
var InnerImageZoom = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) {
var _ref$moveType = _ref.moveType,
moveType = _ref$moveType === void 0 ? 'pan' : _ref$moveType,
_ref$zoomType = _ref.zoomType,
zoomType = _ref$zoomType === void 0 ? 'click' : _ref$zoomType,
src = _ref.src,
sources = _ref.sources,
width = _ref.width,
height = _ref.height,
hasSpacer = _ref.hasSpacer,
_ref$imgAttributes = _ref.imgAttributes,
imgAttributes = _ref$imgAttributes === void 0 ? {} : _ref$imgAttributes,
zoomSrc = _ref.zoomSrc,
_ref$zoomScale = _ref.zoomScale,
zoomScale = _ref$zoomScale === void 0 ? 1 : _ref$zoomScale,
zoomPreload = _ref.zoomPreload,
_ref$fadeDuration = _ref.fadeDuration,
fadeDuration = _ref$fadeDuration === void 0 ? 150 : _ref$fadeDuration,
fullscreenOnMobile = _ref.fullscreenOnMobile,
_ref$mobileBreakpoint = _ref.mobileBreakpoint,
mobileBreakpoint = _ref$mobileBreakpoint === void 0 ? 640 : _ref$mobileBreakpoint,
hideCloseButton = _ref.hideCloseButton,
hideHint = _ref.hideHint,
className = _ref.className,
afterZoomIn = _ref.afterZoomIn,
afterZoomOut = _ref.afterZoomOut;
var container = (0, _react.useRef)(null);
var zoomImg = (0, _react.useRef)(null);
var portal = (0, _react.useRef)(null);
var imgProps = (0, _react.useRef)({});
var _useState = (0, _react.useState)(zoomPreload),
_useState2 = _slicedToArray(_useState, 2),
isActive = _useState2[0],
setIsActive = _useState2[1];
var _useState3 = (0, _react.useState)(false),
_useState4 = _slicedToArray(_useState3, 2),
isTouch = _useState4[0],
setIsTouch = _useState4[1];
var _useState5 = (0, _react.useState)(false),
_useState6 = _slicedToArray(_useState5, 2),
isZoomed = _useState6[0],
setIsZoomed = _useState6[1];
var _useState7 = (0, _react.useState)(false),
_useState8 = _slicedToArray(_useState7, 2),
isFullscreen = _useState8[0],
setIsFullscreen = _useState8[1];
var _useState9 = (0, _react.useState)(false),
_useState10 = _slicedToArray(_useState9, 2),
isDragging = _useState10[0],
setIsDragging = _useState10[1];
var _useState11 = (0, _react.useState)(false),
_useState12 = _slicedToArray(_useState11, 2),
isValidDrag = _useState12[0],
setIsValidDrag = _useState12[1];
var _useState13 = (0, _react.useState)(false),
_useState14 = _slicedToArray(_useState13, 2),
isFading = _useState14[0],
setIsFading = _useState14[1];
var _useState15 = (0, _react.useState)(moveType),
_useState16 = _slicedToArray(_useState15, 2),
currentMoveType = _useState16[0],
setCurrentMoveType = _useState16[1];
var _useState17 = (0, _react.useState)(0),
_useState18 = _slicedToArray(_useState17, 2),
left = _useState18[0],
setLeft = _useState18[1];
var _useState19 = (0, _react.useState)(0),
_useState20 = _slicedToArray(_useState19, 2),
top = _useState20[0],
setTop = _useState20[1];
var handleMouseEnter = function handleMouseEnter(e) {
setIsActive(true);
setIsFading(false);
zoomType === 'hover' && !isZoomed && handleClick(e);
};
var handleTouchStart = function handleTouchStart() {
setIsTouch(true);
setIsFullscreen((0, _images.getFullscreenStatus)(fullscreenOnMobile, mobileBreakpoint));
setCurrentMoveType('drag');
};
var handleClick = function handleClick(e) {
if (isZoomed) {
if (isTouch) {
hideCloseButton && handleClose(e);
} else {
!isValidDrag && zoomOut();
}
return;
}
isTouch && setIsActive(true);
if (zoomImg.current) {
handleLoad({
target: zoomImg.current
});
zoomIn(e);
} else {
imgProps.current.onLoadCallback = zoomIn.bind(_this, e);
}
};
var handleLoad = function handleLoad(e) {
var scaledDimensions = (0, _images.getScaledDimensions)(e.target, zoomScale);
zoomImg.current = e.target;
zoomImg.current.setAttribute('width', scaledDimensions.width);
zoomImg.current.setAttribute('height', scaledDimensions.height);
imgProps.current.scaledDimensions = scaledDimensions;
imgProps.current.bounds = (0, _images.getBounds)(container.current, false);
imgProps.current.ratios = (0, _images.getRatios)(imgProps.current.bounds, scaledDimensions);
if (imgProps.current.onLoadCallback) {
imgProps.current.onLoadCallback();
imgProps.current.onLoadCallback = null;
}
};
var handleMouseMove = function handleMouseMove(e) {
var positions = (0, _events.getMouseMovePositions)(e, imgProps.current);
setLeft(positions.left);
setTop(positions.top);
};
var handleDragStart = function handleDragStart(e) {
var coords = (0, _events.getEventCoords)(e);
imgProps.current.offsets = (0, _images.getOffsets)(coords.x, coords.y, zoomImg.current.offsetLeft, zoomImg.current.offsetTop);
setIsDragging(true);
if (!isTouch) {
imgProps.current.eventPosition = coords;
}
};
var handleDragMove = (0, _react.useCallback)(function (e) {
e.stopPropagation();
var positions = (0, _events.getDragMovePositions)(e, imgProps.current);
setLeft(positions.left);
setTop(positions.top);
}, []);
var handleDragEnd = function handleDragEnd(e) {
setIsDragging(false);
if (!isTouch) {
setIsValidDrag((0, _events.getIsValidDrag)(e, imgProps.current));
}
};
var handleMouseLeave = function handleMouseLeave(e) {
currentMoveType === 'drag' && isZoomed ? handleDragEnd(e) : handleClose(e);
};
var handleClose = function handleClose(e) {
if (!(!isTouch && e.target.classList.contains('iiz__close'))) {
if (!isZoomed || isFullscreen || !fadeDuration) {
handleFadeOut({}, true);
} else {
setIsFading(true);
}
}
zoomOut();
};
var handleFadeOut = function handleFadeOut(e, noTransition) {
if (noTransition || e.propertyName === 'opacity' && container.current.contains(e.target)) {
if (zoomPreload && isTouch || !zoomPreload) {
zoomImg.current = null;
imgProps.current = (0, _images.getImgPropsDefaults)();
setIsActive(false);
}
setIsTouch(false);
setIsFullscreen(false);
setCurrentMoveType(moveType);
setIsFading(false);
}
};
var initialMove = function initialMove(e) {
imgProps.current.offsets = (0, _images.getOffsets)(window.pageXOffset, window.pageYOffset, -imgProps.current.bounds.left, -imgProps.current.bounds.top);
handleMouseMove(e);
};
var initialDrag = function initialDrag(e) {
var initialDragCoords = (0, _events.getInitialDragCoords)(e, imgProps.current, isFullscreen);
imgProps.current.bounds = (0, _images.getBounds)(container.current, isFullscreen);
imgProps.current.offsets = (0, _images.getOffsets)(0, 0, 0, 0);
handleDragMove(_objectSpread(_objectSpread({}, initialDragCoords), {}, {
stopPropagation: function stopPropagation() {}
}));
};
var zoomIn = function zoomIn(e) {
setIsZoomed(true);
currentMoveType === 'drag' ? initialDrag(e) : initialMove(e);
afterZoomIn && afterZoomIn();
};
var zoomOut = function zoomOut() {
setIsZoomed(false);
afterZoomOut && afterZoomOut();
};
var zoomImageProps = {
src: zoomSrc || src,
fadeDuration: isFullscreen ? 0 : fadeDuration,
top: top,
left: left,
isZoomed: isZoomed,
onLoad: handleLoad,
onDragStart: currentMoveType === 'drag' ? handleDragStart : null,
onDragEnd: currentMoveType === 'drag' ? handleDragEnd : null,
onClose: !hideCloseButton && currentMoveType === 'drag' ? handleClose : null,
onFadeOut: isFading ? handleFadeOut : null
};
(0, _react.useEffect)(function () {
imgProps.current = (0, _images.getImgPropsDefaults)();
}, []);
(0, _react.useEffect)(function () {
(0, _images.getFullscreenStatus)(fullscreenOnMobile, mobileBreakpoint) && setIsActive(false);
}, [fullscreenOnMobile, mobileBreakpoint]);
(0, _react.useEffect)(function () {
if (!zoomImg.current) {
return;
}
var eventType = isTouch ? 'touchmove' : 'mousemove';
if (isDragging) {
zoomImg.current.addEventListener(eventType, handleDragMove, {
passive: true
});
} else {
zoomImg.current.removeEventListener(eventType, handleDragMove);
}
}, [isDragging, isTouch, handleDragMove]);
(0, _react.useImperativeHandle)(ref, function () {
return {
container: container.current,
portal: portal.current
};
});
return /*#__PURE__*/_react.default.createElement("figure", {
className: "iiz ".concat(currentMoveType === 'drag' ? 'iiz--drag' : '', " ").concat(className ? className : ''),
style: {
width: width
},
ref: container,
onTouchStart: isZoomed ? null : handleTouchStart,
onClick: handleClick,
onMouseEnter: isTouch ? null : handleMouseEnter,
onMouseMove: currentMoveType === 'drag' || !isZoomed ? null : handleMouseMove,
onMouseLeave: isTouch ? null : handleMouseLeave
}, /*#__PURE__*/_react.default.createElement(_Image.default, {
src: src,
sources: sources,
width: width,
height: height,
hasSpacer: hasSpacer,
imgAttributes: imgAttributes,
fadeDuration: fadeDuration,
isZoomed: isZoomed
}), isActive && /*#__PURE__*/_react.default.createElement(_react.Fragment, null, isFullscreen ? /*#__PURE__*/_react.default.createElement(_FullscreenPortal.default, {
ref: portal
}, /*#__PURE__*/_react.default.createElement(_ZoomImage.default, zoomImageProps)) : /*#__PURE__*/_react.default.createElement(_ZoomImage.default, zoomImageProps)), !hideHint && !isZoomed && /*#__PURE__*/_react.default.createElement("span", {
className: "iiz__btn iiz__hint"
}));
});
InnerImageZoom.displayName = 'InnerImageZoom';
var _default = InnerImageZoom;
exports.default = _default;
;