UNPKG

inner-image-zoom

Version:

A lightweight Vanilla JS package for magnifying an image within its parent container 🔎

1 lines • 12.5 kB
!function(t,i){"object"==typeof exports&&"object"==typeof module?module.exports=i():"function"==typeof define&&define.amd?define([],i):"object"==typeof exports?exports.InnerImageZoom=i():t.InnerImageZoom=i()}(self,(()=>(()=>{"use strict";var t={d:(i,o)=>{for(var e in o)t.o(o,e)&&!t.o(i,e)&&Object.defineProperty(i,e,{enumerable:!0,get:o[e]})},o:(t,i)=>Object.prototype.hasOwnProperty.call(t,i)},i={};return(()=>{function o(t,i){return i?{width:window.innerWidth,height:window.innerHeight,left:0,top:0}:t.getBoundingClientRect()}function e(t,i,o,e){return{x:t-o,y:i-e}}function n(t){return{x:"number"==typeof t.pageX?t.pageX:t.changedTouches[0].pageX,y:"number"==typeof t.pageY?t.pageY:t.changedTouches[0].pageY}}function s(t,i){var o=n(t);return{x:o.x-i.offsets.x,y:o.y-i.offsets.y}}function r(t){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r(t)}function a(t,i){(null==i||i>t.length)&&(i=t.length);for(var o=0,e=new Array(i);o<i;o++)e[o]=t[o];return e}function h(t,i){var o=Object.keys(t);if(Object.getOwnPropertySymbols){var e=Object.getOwnPropertySymbols(t);i&&(e=e.filter((function(i){return Object.getOwnPropertyDescriptor(t,i).enumerable}))),o.push.apply(o,e)}return o}function c(t){for(var i=1;i<arguments.length;i++){var o=null!=arguments[i]?arguments[i]:{};i%2?h(Object(o),!0).forEach((function(i){u(t,i,o[i])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(o)):h(Object(o)).forEach((function(i){Object.defineProperty(t,i,Object.getOwnPropertyDescriptor(o,i))}))}return t}function u(t,i,o){return(i=function(t){var i=function(t,i){if("object"!==r(t)||null===t)return t;var o=t[Symbol.toPrimitive];if(void 0!==o){var e=o.call(t,i);if("object"!==r(e))return e;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(t)}(t,"string");return"symbol"===r(i)?i:String(i)}(i))in t?Object.defineProperty(t,i,{value:o,enumerable:!0,configurable:!0,writable:!0}):t[i]=o,t}t.d(i,{default:()=>m});var l=function(){function t(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:".iiz",i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(i.$el)return this.init(i.$el,i);var o=document.querySelectorAll(t);return o.length?o.length>1?Array.from(o).map((function(o){return new l(t,c(c({},i),{},{$el:o}))})):this.init(o[0],i):void 0}return t.prototype={init:function(t,i){("IMG"===t.tagName||t.querySelector("img"))&&(this.setData(t,i),this.setSelectors(t),this.setListeners())},reinit:function(t){this.uninit(),this.init(this.$el,t)},uninit:function(){this.$container.parentNode&&this.$container.parentNode.replaceChild(this.$el,this.$container),this.$portal&&document.body.removeChild(this.$portal)},setData:function(t,i){this.options=c(c({moveType:"pan",zoomType:"click",zoomScale:1,fadeDuration:150,mobileBreakpoint:640},i),t.dataset),this.options.zoomSrc||(this.options.zoomSrc=t.src||t.querySelector("img").src),this.isTouch=!1,this.isZoomed=!1,this.isValidDrag=!1,this.isClosing=!1,this.currentMoveType=this.options.moveType,this.imgProps={onLoadCallback:null,bounds:{},offsets:{},ratios:{},eventPosition:{},scaledDimensions:{}}},setSelectors:function(t){this.$el=t.cloneNode(!0),this.$container=this.createFigure(t,this.options),this.$img=this.createImg(this.$container),this.$zoomImg=this.createZoomImg(this.$container,this.options),this.$hint=this.createHint(this.$container,this.options),this.$closeButton=this.createCloseButton(this.$container,this.options),this.$portal=this.createPortal(this.options,this.$zoomImg,this.$closeButton)},setListeners:function(){var t=this;this.$container.addEventListener("touchstart",(function(){return t.onTouchStart()}),{passive:!0}),this.$container.addEventListener("mouseenter",(function(i){return t.onMouseEnter(i)})),this.$container.addEventListener("click",(function(i){return t.onClick(i)})),this.$container.addEventListener("mousemove",(function(i){return t.onMouseMove(i)}),{passive:!0}),this.$container.addEventListener("mouseleave",(function(i){return t.onMouseLeave(i)})),this.$zoomImg.addEventListener("touchstart",(function(i){return t.onDragStart(i)}),{passive:!0}),this.$zoomImg.addEventListener("touchend",(function(i){return t.onDragEnd(i)}),{passive:!0}),this.$zoomImg.addEventListener("mousedown",(function(i){return t.onDragStart(i)})),this.$zoomImg.addEventListener("mouseup",(function(i){return t.onDragEnd(i)})),this.$zoomImg.onload=function(){return t.onLoad()},this.$zoomImg.addEventListener("transitionend",(function(i){return t.onTransitionEnd(i)})),this.$closeButton&&this.$closeButton.addEventListener("click",(function(i){return t.onClose(i)})),this.dragMove=function(i){return t.onDragMove(i)}},createFigure:function(t,i){var o,e,n=t;return"IMG"!==t.tagName&&"PICTURE"!==t.tagName||(n=document.createElement("figure"),t.parentNode.insertBefore(n,t),t.classList.remove("iiz"),n.appendChild(t)),(o=n.classList).add.apply(o,["iiz"].concat(function(t){if(Array.isArray(t))return a(t)}(e="drag"===i.moveType?["iiz--drag"]:[])||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(e)||function(t,i){if(t){if("string"==typeof t)return a(t,i);var o=Object.prototype.toString.call(t).slice(8,-1);return"Object"===o&&t.constructor&&(o=t.constructor.name),"Map"===o||"Set"===o?Array.from(t):"Arguments"===o||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(o)?a(t,i):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}())),n},createImg:function(t){var i=t.querySelector("img");return i.classList.add("iiz__img"),i.style.transition="opacity 0ms linear, visibility 0ms linear",i},createZoomImg:function(t,i){var o=document.createElement("img");return o.classList.add("iiz__zoom-img"),o.alt="",o.draggable=!1,o.style.left="0px",o.style.top="0px",o.style.transition="opacity ".concat(i.fadeDuration,"ms linear, visibility ").concat(i.fadeDuration,"ms linear"),i.zoomPreload&&(o.setAttribute("src",i.zoomSrc),t.appendChild(o)),o},createHint:function(t,i){if(i.hideHint)return null;var o=document.createElement("span");return o.classList.add("iiz__btn","iiz__hint"),t.appendChild(o),o},createCloseButton:function(t,i){if(i.hideCloseButton)return null;var o=document.createElement("button");return o.classList.add("iiz__btn","iiz__close"),o.setAttribute("aria-label","Zoom Out"),o.style.transition="opacity ".concat(i.fadeDuration,"ms linear, visibility ").concat(i.fadeDuration,"ms linear"),o},createPortal:function(t,i,o){var e=this;if(!t.fullscreenOnMobile)return null;var n=document.createElement("div");return n.classList.add("iiz__zoom-portal"),n.appendChild(i).setAttribute("src",this.options.zoomSrc),o&&n.appendChild(o),o?n.appendChild(o):i.addEventListener("click",(function(t){return e.onClick(t)})),n},onTouchStart:function(){var t,i;this.isZoomed||(this.isTouch=!0,this.isFullscreen=(t=this.options.fullscreenOnMobile,i=this.options.mobileBreakpoint,t&&window.matchMedia&&window.matchMedia("(max-width: ".concat(i,"px)")).matches),this.currentMoveType="drag")},onMouseEnter:function(t){this.isTouch||(this.isClosing=!1,this.$container.appendChild(this.$zoomImg),this.$zoomImg.src!==this.options.zoomSrc&&this.$zoomImg.setAttribute("src",this.options.zoomSrc),this.$closeButton&&this.$container.appendChild(this.$closeButton),"hover"===this.options.zoomType&&!this.isZoomed&&this.onClick(t))},onClick:function(t){this.isZoomed?this.isTouch?!this.$closeButton&&this.onClose(t):!this.isValidDrag&&this.zoomOut():(this.isTouch&&(this.isFullscreen?document.body.appendChild(this.$portal):(this.$container.appendChild(this.$zoomImg).setAttribute("src",this.options.zoomSrc),this.$closeButton&&this.$container.appendChild(this.$closeButton))),this.$zoomImg.complete?(this.onLoad(),this.zoomIn(t)):this.imgProps.onLoadCallback=this.zoomIn.bind(this,t))},onLoad:function(){var t,i,e,n,s=(t=this.$zoomImg,i=this.options.zoomScale,{width:t.naturalWidth*i,height:t.naturalHeight*i});this.$zoomImg.setAttribute("width",s.width),this.$zoomImg.setAttribute("height",s.height),this.imgProps.scaledDimensions=s,this.imgProps.bounds=o(this.$img,!1),this.imgProps.ratios=(e=this.imgProps.bounds,{x:((n=s).width-e.width)/e.width,y:(n.height-e.height)/e.height}),this.imgProps.onLoadCallback&&(this.imgProps.onLoadCallback(),this.imgProps.onLoadCallback=null)},onMouseMove:function(t){if("drag"!==this.currentMoveType&&this.isZoomed){var i=function(t,i){var o=s(t,i);return{left:Math.max(Math.min(o.x,i.bounds.width),0)*-i.ratios.x,top:Math.max(Math.min(o.y,i.bounds.height),0)*-i.ratios.y}}(t,this.imgProps);this.$zoomImg.style.left="".concat(i.left,"px"),this.$zoomImg.style.top="".concat(i.top,"px")}},onMouseLeave:function(t){this.isTouch||("drag"===this.currentMoveType&&this.isZoomed?this.onDragEnd(t):this.onClose(t))},onDragStart:function(t){if("drag"===this.currentMoveType){var i=n(t);this.imgProps.offsets=e(i.x,i.y,this.$zoomImg.offsetLeft,this.$zoomImg.offsetTop),this.$zoomImg.addEventListener(this.isTouch?"touchmove":"mousemove",this.dragMove,{passive:!0}),this.isTouch||(this.imgProps.eventPosition=i)}},onDragMove:function(t){if(t.stopPropagation(),"drag"===this.currentMoveType&&this.isZoomed){var i=function(t,i){var o=s(t,i);return{left:Math.max(Math.min(o.x,0),-1*(i.scaledDimensions.width-i.bounds.width)),top:Math.max(Math.min(o.y,0),-1*(i.scaledDimensions.height-i.bounds.height))}}(t,this.imgProps);this.$zoomImg.style.left="".concat(i.left,"px"),this.$zoomImg.style.top="".concat(i.top,"px")}},onDragEnd:function(t){"drag"===this.currentMoveType&&(this.$zoomImg.removeEventListener(this.isTouch?"touchmove":"mousemove",this.dragMove),this.isTouch||(this.isValidDrag=function(t,i){var o=Math.abs(t.pageX-i.eventPosition.x),e=Math.abs(t.pageY-i.eventPosition.y);return o>5||e>5}(t,this.imgProps)))},onClose:function(t){t.stopPropagation(),t.target.classList.contains("iiz__close")&&!this.isTouch||(this.isZoomed&&!this.isFullscreen&&this.options.fadeDuration?this.isClosing=!0:this.cleanup()),this.isZoomed&&this.zoomOut()},onTransitionEnd:function(t){this.isClosing&&"opacity"===t.propertyName&&t.target===this.$zoomImg&&this.cleanup()},initialMove:function(t){this.imgProps.offsets=e(window.pageXOffset,window.pageYOffset,-this.imgProps.bounds.left,-this.imgProps.bounds.top),this.onMouseMove(t)},initialDrag:function(t){var i=function(t,i,o){var e=(t.pageX-(window.pageXOffset+i.bounds.left))*-i.ratios.x,n=(t.pageY-(window.pageYOffset+i.bounds.top))*-i.ratios.y;return{pageX:e+(o?(window.innerWidth-i.bounds.width)/2:0),pageY:n+(o?(window.innerHeight-i.bounds.height)/2:0)}}(t,this.imgProps,this.isFullscreen);this.imgProps.bounds=o(this.$img,this.isFullscreen),this.imgProps.offsets=e(0,0,0,0),this.onDragMove(c(c({},i),{},{stopPropagation:function(){}}))},zoomIn:function(t){this.isZoomed=!0,this.$zoomImg.classList.add("iiz__zoom-img--visible"),this.$zoomImg.style.transitionDuration="".concat(this.isFullscreen?0:this.options.fadeDuration,"ms"),this.$img.classList.add("iiz__img--hidden"),this.$img.style.transitionDelay="".concat(this.isFullscreen?0:this.options.fadeDuration,"ms"),this.$closeButton&&"drag"===this.currentMoveType&&(this.$closeButton.classList.add("iiz__close--visible"),this.$closeButton.style.transitionDuration="".concat(this.isFullscreen?0:this.options.fadeDuration,"ms")),"drag"===this.currentMoveType?this.initialDrag(t):this.initialMove(t),this.options.afterZoomIn&&this.options.afterZoomIn()},zoomOut:function(){this.isZoomed=!1,this.$zoomImg.classList.remove("iiz__zoom-img--visible"),this.$img.classList.remove("iiz__img--hidden"),this.$img.style.transitionDelay="0ms",this.$closeButton&&this.$closeButton.classList.remove("iiz__close--visible"),this.options.afterZoomOut&&this.options.afterZoomOut()},cleanup:function(){(this.options.zoomPreload&&this.isTouch||!this.options.zoomPreload)&&(this.isFullscreen?document.body.removeChild(this.$portal):(this.$container.removeChild(this.$zoomImg),this.$closeButton&&this.$container.removeChild(this.$closeButton)),this.imgProps.current={onLoadCallback:null,bounds:{},offsets:{},ratios:{},eventPosition:{},scaledDimensions:{}}),this.isTouch=!1,this.isFullscreen=!1,this.currentMoveType=this.options.moveType,this.isClosing=!1}},t}();const m=l})(),i.default})()));