maz-ui
Version:
A standalone components library for Vue.Js 3 & Nuxt.Js 3
124 lines (110 loc) • 10.1 kB
JavaScript
var style=`
.maz-zoom-img {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
padding: 1rem;
z-index: 1050;
background-color: hsla(238, 15%, 40%, 0.7);
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
.maz-zoom-img,
.maz-zoom-img * {
box-sizing: border-box;
}
.maz-zoom-img .maz-zoom-img__wrapper {
position: relative;
display: flex;
justify-content: center;
align-items: center;
min-width: 0;
min-height: 0;
max-width: 100%;
max-height: 100%;
transition: all 300ms ease-in-out;
opacity: 0;
transform: scale(0.5);
}
.maz-zoom-img.maz-animate .maz-zoom-img__wrapper {
opacity: 1;
transform: scale(1);
}
.maz-zoom-img.maz-animate .maz-zoom-img__loader {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
background-color: hsla(238, 15%, 40%, 0.7);
border-radius: 1rem;
z-index: 2;
min-width: 60px;
min-height: 60px;
}
.maz-zoom-img.maz-animate .maz-zoom-img__loader[hidden] {
display: none;
}
@-webkit-keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.maz-zoom-img.maz-animate .maz-zoom-img__loader__svg {
animation: spin .6s linear infinite;
}
.maz-zoom-img img {
max-width: 100%;
max-height: 100%;
min-width: 0;
border-radius: 1rem;
}
.maz-zoom-img .maz-zoom-btn {
margin: 0 auto;
border: none;
background-color: hsla(0, 0%, 7%, 0.5);
box-shadow: 0 0 0.5rem 0 hsla(0, 0%, 0%, 0.2);
height: 2.2rem;
min-height: 2.2rem;
width: 2.2rem;
min-width: 2.2rem;
display: flex;
align-items: center;
justify-content: center;
border-radius: 2.2rem;
cursor: pointer;
flex: 0 0 auto;
outline: none;
}
.maz-zoom-img .maz-zoom-btn svg {
fill: white;
}
.maz-zoom-img .maz-zoom-btn.maz-zoom-btn--close {
position: absolute;
top: 0.5rem;
right: 0.5rem;
z-index: 1;
}
.maz-zoom-img .maz-zoom-btn.maz-zoom-btn--previous {
position: absolute;
left: 0.5rem;
z-index: 1;
}
.maz-zoom-img .maz-zoom-btn.maz-zoom-btn--next {
position: absolute;
right: 0.5rem;
z-index: 1;
}
.maz-zoom-img .maz-zoom-btn:hover {
background-color: hsl(0, 0%, 0%);
}`;var svgs={close:`<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>`,next:`<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>`,previous:`<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>`,spinner:`<svg width="40px" height="40px" version="1.1" xmlns="http://www.w3.org/2000/svg" fill="currentColor" x="0px" y="0px" viewBox="0 0 50 50" xml:space="preserve" class="maz-zoom-img__loader__svg" data-v-6d1cb50c=""><path d="M43.935,25.145c0-10.318-8.364-18.683-18.683-18.683c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615c8.072,0,14.615,6.543,14.615,14.615H43.935z"></path></svg>`};var StateClass=function(StateClass){return StateClass.OPEN=`maz-is-open`,StateClass}(StateClass||{});var ZoomImgHandler=class{options;loader;wrapper;img;keydownHandler;onImgLoadedCallback;buttonsAdded;defaultOptions={scale:!0,blur:!0,disabled:!1};mouseEnterListener=void 0;mouseLeaveListener=void 0;renderPreviewListener=void 0;constructor(binding){if(!binding.value)throw Error('[MazUI](zoom-img) Image path must be defined. Ex: `v-zoom-img="<PATH_TO_IMAGE>"`');if(typeof binding.value==`object`&&!binding.value.src)throw Error(`[maz-ui](zoom-img) src of image must be provided`);this.buttonsAdded=!1,this.options=this.buildOptions(binding),this.keydownHandler=this.keydownLister.bind(this),this.loader=this.getLoader(),this.wrapper=document.createElement(`div`),this.wrapper.classList.add(`maz-zoom-img__wrapper`),this.wrapper.prepend(this.loader),this.img=document.createElement(`img`),this.onImgLoadedCallback=this.onImgLoaded.bind(this),this.imgEventHandler(!0)}buildOptions(binding){return{...this.defaultOptions,...typeof binding.value==`object`?binding.value:{src:binding.value}}}get allInstances(){return[...document.querySelectorAll(`.maz-zoom-img-instance`)]}create(el){this.options.disabled||(el.style.cursor=`pointer`,setTimeout(()=>el.classList.add(`maz-zoom-img-instance`)),el.setAttribute(`data-zoom-src`,this.options.src),this.options.alt&&el.setAttribute(`data-zoom-alt`,this.options.alt),el.style.transition=`all 300ms ease-in-out`,this.mouseEnterListener=()=>this.mouseEnter(el),this.mouseLeaveListener=()=>this.mouseLeave(el),this.renderPreviewListener=()=>this.renderPreview(el,this.options),el.addEventListener(`mouseenter`,this.mouseEnterListener),el.addEventListener(`mouseleave`,this.mouseLeaveListener),el.addEventListener(`click`,this.renderPreviewListener))}update(binding){this.options=this.buildOptions(binding)}remove(el){this.imgEventHandler(!1),this.mouseEnterListener&&el.removeEventListener(`mouseenter`,this.mouseEnterListener),this.mouseLeaveListener&&el.removeEventListener(`mouseleave`,this.mouseLeaveListener),this.renderPreviewListener&&el.removeEventListener(`click`,this.renderPreviewListener),this.mouseEnterListener=void 0,this.mouseLeaveListener=void 0,this.renderPreviewListener=void 0,el.classList.remove(`maz-zoom-img-instance`),el.removeAttribute(`data-zoom-src`),el.removeAttribute(`data-zoom-alt`),el.style.cursor=``}renderPreview(el,options){el.classList.add(StateClass.OPEN),this.addStyle(style);let container=document.createElement(`div`);container.classList.add(`maz-zoom-img`),container.setAttribute(`id`,`MazImgPreviewFullsize`),container.addEventListener(`click`,e=>{container.isEqualNode(e.target)&&this.closePreview()}),typeof options==`object`&&(this.img.setAttribute(`src`,options.src),options.alt&&this.img.setAttribute(`alt`,options.alt),this.img.id=`MazImgElement`),this.wrapper.append(this.img),container.append(this.wrapper),document.body.append(container),this.keyboardEventHandler(!0),setTimeout(()=>{container&&container.classList.add(`maz-animate`)},100)}onImgLoaded(){this.wrapper.style.width=`${this.img.width}px`,this.wrapper.style.minWidth=`200px`,this.loader.hidden=!0;let closeButton=this.getButton();let buttons=[];let hasMultipleInstance=this.allInstances.length>1;if(!this.buttonsAdded){if(this.buttonsAdded=!0,hasMultipleInstance){let previousButton=this.getButton(`previous`);let nextButton=this.getButton(`next`);buttons.push(previousButton,nextButton)}this.wrapper.append(closeButton),hasMultipleInstance&&(this.wrapper.prepend(buttons[0]),this.wrapper.append(buttons[1]))}}getLoader(){let loader=document.createElement(`div`);return loader.classList.add(`maz-zoom-img__loader`),loader.innerHTML=svgs.spinner,loader}mouseLeave(el){this.options.scale&&(el.style.transform=``),this.options.blur&&(el.style.filter=``),el.style.zIndex=``}mouseEnter(el){el.style.zIndex=`1`,this.options.scale&&(el.style.transform=`scale(1.1)`),this.options.blur&&(el.style.filter=`blur(2px)`)}keydownLister(e){e.preventDefault(),(e.key===`Escape`||e.key===` `)&&this.closePreview(),(e.key===`ArrowLeft`||e.key===`ArrowRight`)&&this.nextPreviousImage(e.key===`ArrowRight`)}getButton(iconName=`close`){let button=document.createElement(`button`);button.innerHTML=svgs[iconName];let getAction=()=>iconName===`close`?this.closePreview():this.allInstances?this.nextPreviousImage(iconName===`next`):null;return button.addEventListener(`click`,()=>{getAction()}),button.classList.add(`maz-zoom-btn`),button.classList.add(`maz-zoom-btn--${iconName}`),button}closePreview(){let container=document.querySelector(`#MazImgPreviewFullsize`);let style=document.querySelector(`#MazPreviewStyle`);let instance=document.querySelector(`.maz-zoom-img-instance.maz-is-open`);instance&&instance.classList.remove(StateClass.OPEN),container&&container.classList.remove(`maz-animate`),this.keyboardEventHandler(!1),setTimeout(()=>{container&&container.remove(),style&&style.remove()},300)}getNewInstanceIndex(newInstanceIndex){let nextIndex=newInstanceIndex;return nextIndex<0?nextIndex=this.allInstances.length-1:nextIndex>=this.allInstances.length&&(nextIndex=0),nextIndex}nextPreviousImage(isNext){let selectNextInstance=isNext;let currentInstance=document.querySelector(`.maz-zoom-img-instance.maz-is-open`);if(currentInstance){let currentInstanceIndex=this.allInstances.indexOf(currentInstance);let newInstanceIndex=selectNextInstance?currentInstanceIndex+1:currentInstanceIndex-1;let nextInstance=this.allInstances[this.getNewInstanceIndex(newInstanceIndex)];nextInstance&&this.useNextInstance(currentInstance,nextInstance)}}useNextInstance(currentInstance,nextInstance){currentInstance.classList.remove(StateClass.OPEN),nextInstance.classList.add(StateClass.OPEN);let src=nextInstance.getAttribute(`data-zoom-src`);let alt=nextInstance.getAttribute(`data-zoom-alt`);this.wrapper.style.width=``,this.loader.hidden=!1,src&&this.img.setAttribute(`src`,src),alt&&this.img.setAttribute(`alt`,alt)}addStyle(styleString){let style=document.createElement(`style`);style.id=`MazPreviewStyle`,style.textContent=styleString,document.head.append(style)}keyboardEventHandler(add){if(add)return document.addEventListener(`keydown`,this.keydownHandler);document.removeEventListener(`keydown`,this.keydownHandler)}imgEventHandler(add){if(add)return this.img.addEventListener(`load`,this.onImgLoadedCallback);this.img.removeEventListener(`load`,this.onImgLoadedCallback)}};var instance;var vZoomImg={created(el,binding){instance=new ZoomImgHandler(binding),instance.create(el)},updated(_el,binding){instance.update(binding)},unmounted(el){instance.remove(el)}};var plugin={install(app){app.directive(`zoom-img`,vZoomImg)}};export{vZoomImg as n,plugin as t};