@lylech/react-image-magnifier
Version:
An image magnifier complete with thumbnail ribbon. Lightweight yet customizable.
322 lines (312 loc) • 17.1 kB
JavaScript
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 };