UNPKG

@lylech/react-image-magnifier

Version:

An image magnifier complete with thumbnail ribbon. Lightweight yet customizable.

322 lines (312 loc) 17.1 kB
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } 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 _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } 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 _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 _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 _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); } var LylechImageMagnifierJS = /*#__PURE__*/function () { function LylechImageMagnifierJS(args) { var _this = this; _classCallCheck(this, LylechImageMagnifierJS); _defineProperty(this, "nextImage", function () { var idxNextImage = (_this.selectedIdxImage + 1) % _this.arrayOfImagePaths.length; _this.thumbclick(_this.arrayOfImagePaths[idxNextImage], _this.oProductImg, _this.oProduct, idxNextImage, true); }); _defineProperty(this, "previousImage", function () { var idxNextImage = (_this.selectedIdxImage - 1 + _this.arrayOfImagePaths.length) % _this.arrayOfImagePaths.length; // if (idxNextImage<0) idxNextImage=this.arrayOfImagePaths.length-1; _this.thumbclick(_this.arrayOfImagePaths[idxNextImage], _this.oProductImg, _this.oProduct, idxNextImage, true); }); _defineProperty(this, "setCurrentImage", function (idxImage, doTriggerAnimation) { _this.selectedIdxImage = idxImage; if (doTriggerAnimation && _this.fnClickHandler) _this.fnClickHandler(idxImage); _this.arrayOfThumbnailContainers[idxImage].classList.add("active"); if (typeof _this.idxPreviousImage !== 'undefined' && _this.idxPreviousImage !== idxImage) _this.arrayOfThumbnailContainers[_this.idxPreviousImage].classList.remove("active"); _this.idxPreviousImage = idxImage; }); _defineProperty(this, "thumbclick", function (strImg, oProductImage, oProductImageContainer, idxImage, doTriggerAnimation) { if (doTriggerAnimation && _this.idxPreviousImage === idxImage) return; oProductImage.style.width = "0"; oProductImage.style.height = "0"; var idxPreviousImage = _this.idxPreviousImage; oProductImage.onload = function () { var containerWidth = oProductImageContainer.scrollWidth; var containerHeight = oProductImageContainer.scrollHeight; var nw = oProductImage.naturalWidth; var nh = oProductImage.naturalHeight; var imgAspectRatio = nw / nh; var containerAspectRatio = containerWidth / containerHeight; if (imgAspectRatio > containerAspectRatio) { oProductImage.style.width = containerWidth + "px"; oProductImage.style.height = parseInt(nh * containerWidth / nw) + "px"; } else { oProductImage.style.width = parseInt(nw * containerHeight / nh) + "px"; oProductImage.style.height = containerHeight + "px"; } if (doTriggerAnimation && idxPreviousImage !== idxImage) { oProductImageContainer.classList.remove("selected"); void oProductImageContainer.offsetWidth; oProductImageContainer.classList.add("selected"); } }; oProductImage.setAttribute("src", strImg); _this.setCurrentImage(idxImage, doTriggerAnimation); }); _defineProperty(this, "createThumbnails", function (arrayOfImagePaths, //string: path to image files for thumbnails oThumbnails, //DIV : container to which to add thumbnail oProductImg, //IMG : Product display: img oProductImgContainer, //DIV : Product display: container for img fnClick //Function: Callback for thumbnail click event handler ) { var arrayOfThumbnailContainers = []; arrayOfImagePaths.forEach(function (strImg, idxImage) { var oSpan = document.createElement("span"); oSpan.className = "lfc-rim-thumbnail-outer"; oSpan.style.setProperty('--i', idxImage); var oDiv = document.createElement('div'); oDiv.className = "lfc-rim-thumbnail"; oDiv.style.backgroundImage = "url('" + strImg + "')"; oDiv.style.setProperty('--i', idxImage); oDiv.addEventListener('click', function (e) { fnClick(strImg, oProductImg, oProductImgContainer, idxImage, true); }); // oThumbnails.appendChild(oDiv); // arrayOfThumbnailContainers.push(oDiv); oSpan.appendChild(oDiv); oThumbnails.appendChild(oSpan); arrayOfThumbnailContainers.push(oSpan); }); return arrayOfThumbnailContainers; }); if (!args.container) { console.error("container must be specfied"); return; } if (args.container.getAttribute("inuse")) { console.warn("Attempt to reinitialize class prevented!"); window.location.reload(); } this.arrayOfImagePaths = args.arrayOfImagePaths || []; this.arrayOfImageZoomFactors = args.arrayOfImageZoomFactors || []; for (var i = this.arrayOfImageZoomFactors.length; i < this.arrayOfImagePaths.length; i++) { this.arrayOfImageZoomFactors.push(2); } new Array(this.arrayOfImagePaths.length).fill(2); this.fnClickHandler = args.fnClickHandler; this.initialSelection = args.initialSelection || 0; this.container = args.container; this.container.setAttribute("inuse", "true"); var _this$createScaffoldi = this.createScaffolding(this.container), _this$createScaffoldi2 = _slicedToArray(_this$createScaffoldi, 3), oProduct = _this$createScaffoldi2[0], _oThumbnails = _this$createScaffoldi2[1], _oProductImg = _this$createScaffoldi2[2]; this.oProduct = oProduct; this.oProductImg = _oProductImg; window.addEventListener("resize", function (e) { clearTimeout(_this.resizeListener); _this.resizeListener = setTimeout(function () { return fnResizeListener(); }, 100); }); var fnResizeListener = function fnResizeListener(e) { _this.thumbclick(_this.arrayOfImagePaths[_this.selectedIdxImage], _oProductImg, oProduct, _this.selectedIdxImage, false); }; var touchmoveListener = function touchmoveListener(e) { e.preventDefault(); var ee = []; ee.pageX = e.touches[0].pageX; ee.pageY = e.touches[0].pageY; hoverListener(ee); }; var hoverListener = function hoverListener(e) { var bspaceX = -(e.pageX - oProduct.offsetLeft - oProduct.clientWidth / 2) / oProduct.clientWidth * 100; var bspaceY = -(e.pageY - oProduct.offsetTop - oProduct.clientHeight / 2) / oProduct.clientHeight * 100; if (bspaceX < -25) bspaceX = -25;else if (bspaceX > 25) bspaceX = 25; if (bspaceY < -25) bspaceY = -25;else if (bspaceY > 25) bspaceY = 25; var imageRangeX = _oProductImg.width - oProduct.clientWidth; var imageRangeY = _oProductImg.height - oProduct.clientHeight; if (imageRangeX < 0) imageRangeX = 0; if (imageRangeY < 0) imageRangeY = 0; var imageX = (bspaceX + 25) * 2 / 100 * imageRangeX; var imageY = (bspaceY + 25) * 2 / 100 * imageRangeY; var xlatX = (_oProductImg.width - oProduct.clientWidth) / 2; var xlatY = (_oProductImg.height - oProduct.clientHeight) / 2; if (xlatX < 0) xlatX = 0; if (xlatY < 0) xlatY = 0; imageX = imageX - xlatX; imageY = imageY - xlatY; _oProductImg.style.left = imageX + "px"; _oProductImg.style.top = imageY + "px"; return; }; var wheelListener = function wheelListener(e) { //console.log("wheelEvent: %o",e ); if (e.wheelDelta > 0) ; }; oProduct.addEventListener("mouseenter", function (e) { var zoomFactor = _this.arrayOfImageZoomFactors[_this.selectedIdxImage]; _oProductImg.bag = { width: _oProductImg.style.width, height: _oProductImg.style.height }; _oProductImg.style.width = _oProductImg.width * zoomFactor + "px"; _oProductImg.style.height = _oProductImg.height * zoomFactor + "px"; oProduct.addEventListener("mousemove", hoverListener); oProduct.addEventListener("touchmove", touchmoveListener); oProduct.addEventListener("wheel", wheelListener); }); oProduct.addEventListener("mouseleave", function (e) { oProduct.removeEventListener("mousemove", hoverListener); oProduct.removeEventListener("touchmove", touchmoveListener); oProduct.removeEventListener("wheel", wheelListener); _oProductImg.style.width = _oProductImg.bag["width"]; _oProductImg.style.height = _oProductImg.bag["height"]; _oProductImg.style.left = 0; _oProductImg.style.top = 0; }); this.arrayOfThumbnailContainers = this.createThumbnails(this.arrayOfImagePaths, _oThumbnails, _oProductImg, oProduct, this.thumbclick); this.thumbclick(this.arrayOfImagePaths[this.initialSelection], _oProductImg, oProduct, this.initialSelection, true); } _createClass(LylechImageMagnifierJS, [{ key: "createScaffolding", value: function createScaffolding(container) { var oDivLeft = document.createElement('div'); oDivLeft.className = "lfc-rim-main"; var oDivProduct = document.createElement('div'); oDivProduct.className = "lfc-rim-product"; var oImgProduct = document.createElement('img'); oImgProduct.className = "lfc-rim-product-img"; var oDivThumbnails = document.createElement('div'); oDivThumbnails.className = "lfc-rim-thumbnails"; oDivProduct.appendChild(oImgProduct); oDivLeft.appendChild(oDivProduct); oDivLeft.appendChild(oDivThumbnails); container.appendChild(oDivLeft); return [oDivProduct, oDivThumbnails, oImgProduct]; } }]); return LylechImageMagnifierJS; }(); function styleInject(css, ref) { if ( ref === void 0 ) ref = {}; var insertAt = ref.insertAt; if (!css || typeof document === 'undefined') { return; } var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; if (insertAt === 'top') { if (head.firstChild) { head.insertBefore(style, head.firstChild); } else { head.appendChild(style); } } else { head.appendChild(style); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } } var css_248z = "/*Container element - React context*/\r\n.react-image-magnifier{\r\n\tmin-width: 320px;\r\n\twidth: 60vw;\r\n\theight: 80vh;\r\n\tdisplay: flex;\r\n\tjustify-content: center;\r\n\r\n\talign-items: center;\r\n\tborder: 1px solid gray;\r\n\tborder-radius: 4px;\r\n}\r\n\r\n/*Container element - JS context*/\r\ndiv.lfc-rim-main{\r\n\twidth: 100%;\r\n\theight: 100%;\r\n\tdisplay: block;\r\n}\r\n\r\n/*Product Pane*/\r\ndiv.lfc-rim-product{\r\n\twidth: 100%;\r\n\theight: 80%;\r\n\tdisplay: flex;\r\n\tjustify-content: center;\r\n\talign-items: center;\r\n\toverflow: hidden;\r\n\tposition: relative;\r\n}\r\n\r\n/* Image element in Product Pane*/\r\nimg.lfc-rim-product-img{\r\n\theight: 0;\r\n\twidth: 0;\r\n\tposition: relative;\r\n}\r\n\r\n@keyframes lfc-mag-kf-anim-scaleup {\r\n\tfrom {scale: 33%;/*transform: rotate(0deg);*/}\r\n\tto {scale: 100%;/*transform: rotate(360deg)*/}\r\n}\r\n\r\n /* Class selected is applied when new thumbnail is selected*/\r\n .lfc-rim-product.selected img{\r\n\tanimation: lfc-mag-kf-anim-scaleup 0.1s;\r\n}\r\n\r\n/*Thumbnails container*/\r\ndiv.lfc-rim-thumbnails{\r\n\twidth: 100%;\r\n\theight: 20%;\r\n\r\n\tdisplay: flex;\r\n\tjustify-content: center;\r\n\tflex-direction: row;\r\n}\r\n\r\n/*Thumbnail*/\r\nspan.lfc-rim-thumbnail-outer{\r\n\tposition: relative;\r\n\twidth: 100%;\r\n\theight: 100%;\r\n}\r\n\r\ndiv.lfc-rim-thumbnail{\r\n\tposition: relative;\r\n\twidth: 100%;\r\n\theight: 100%;\r\n\tmargin-right: 1px;\r\n\tborder: 1px solid #AAA;\r\n\tborder-radius: 4px;\r\n\r\n\tbackground-position: center;\r\n\tbackground-repeat: no-repeat;\r\n\tbackground-size: contain;\r\n\r\n\t/* transform-origin: 100px;\r\n\ttransform: rotate(calc(90deg*var(--i))); */\r\n\r\n}\r\n\r\n/*Currently selected Thumbnail */\r\nspan.lfc-rim-thumbnail-outer.active div.lfc-rim-thumbnail{\r\n\tborder: 4px solid gold;\r\n\tbackground-color: silver;\r\n\tborder-radius: 8px;\r\n\tscale:1.1 1.1;\r\n\ttransition: scale 0.5s;\r\n\tz-index: 1;\r\n\tcursor: default;\r\n}\r\n\r\n/*Hover over Thumbnail, */\r\n.lfc-rim-thumbnail:hover{\r\n\tborder: 4px solid goldenrod;\r\n\tbackground-color: #6F3232;\r\n\tborder-radius: 30%;\r\n\tscale:1.3;\r\n\tz-index: 2;\r\n\tcursor: pointer;\r\n}\r\n\r\n/* +++ Thumbnail Ribbon positioning +++ */\r\n.ribbon-top .lfc-rim-main{\r\n\tdisplay: flex;\r\n\tflex-flow: column-reverse;\r\n}\r\n\r\n.ribbon-left .lfc-rim-main{\r\n\tdisplay: flex;\r\n\tflex-direction: row-reverse;\r\n}\r\n\r\n.ribbon-right .lfc-rim-main{\r\n\tdisplay: flex;\r\n\tflex-direction: row;\r\n}\r\n\r\n.ribbon-hide div.lfc-rim-main div.lfc-rim-product{\r\n\twidth: 100%;\r\n\theight: 100%;\r\n}\r\n\r\n.ribbon-hide div.lfc-rim-main div.lfc-rim-thumbnails{\r\n\tdisplay: none;\r\n}\r\n\r\n.ribbon-left div.lfc-rim-main div.lfc-rim-product,\r\n.ribbon-right div.lfc-rim-main div.lfc-rim-product{\r\n\twidth: 80%;\r\n\theight: 100%;\r\n}\r\n.ribbon-left div.lfc-rim-main div.lfc-rim-thumbnails,\r\n.ribbon-right div.lfc-rim-main div.lfc-rim-thumbnails{\r\n\twidth: 20%;\r\n\theight: 100%;\r\n\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n}\r\n/* --- Thumbnail Ribbon positioning --- */\r\n\r\n/* +++ Previous/Next Buttons +++ */\r\nbutton.rim-button{\r\n border-radius: 8px;\r\n padding: 0.5rem 1rem 0.5rem 1rem;\r\n\tcursor: pointer;\r\n}\r\n\r\nbutton.rim-button:hover{\r\n\t/* scale: 1.2; */\r\n\tbackground-color: #DCDCDC;\r\n\t/* font-weight: 600; */\r\n}\r\n\r\nbutton.lfc-rim-btn-prev{\r\n\twidth: 10%;\r\n\theight: 100%;\r\n\tposition: absolute;\r\n\tleft: 0;\r\n\tz-index: 1;\r\n\topacity: .5;\r\n\tcursor: pointer;\r\n}\r\nbutton.lfc-rim-btn-next{\r\n\twidth: 10%;\r\n\theight: 100%;\r\n\tposition: absolute;\r\n\tright: 0;\r\n\tz-index: 1;\r\n\topacity: .5;\r\n\tcursor: pointer;\r\n}\r\n\r\n/* --- Previous/Next Buttons --- */"; styleInject(css_248z); export { css_248z as RIMDefaultCss, LylechImageMagnifierJS as RIMagnifier };