vue-carousel-3d
Version:
Beautiful, flexible and touch supported 3D Carousel for Vue.js
5 lines (4 loc) • 19.7 kB
JavaScript
(function(){try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode(`.carousel-3d-slide{opacity:0;visibility:hidden;box-sizing:border-box;text-align:left;background-color:#ccc;background-size:cover;border-style:solid;border-color:#0006;border-radius:1px;margin:0;display:block;position:absolute;top:0;overflow:hidden}.carousel-3d-slide img{width:100%}.carousel-3d-slide.current{z-index:999;opacity:1!important;visibility:visible!important;transform:none!important}.carousel-3d-controls[data-v-35bea2a2]{z-index:1000;width:100%;height:0;margin-top:-30px;position:absolute;top:50%;left:0}.next[data-v-35bea2a2],.prev[data-v-35bea2a2]{z-index:1010;color:#333;-webkit-user-select:none;user-select:none;background:0 0;border:0;width:60px;height:60px;padding:0;font-size:60px;line-height:60px;text-decoration:none;position:absolute;top:0}.next[data-v-35bea2a2]:hover,.prev[data-v-35bea2a2]:hover{cursor:pointer;opacity:.7}.prev[data-v-35bea2a2]{text-align:left;left:10px}.next[data-v-35bea2a2]{text-align:right;right:10px}.disabled[data-v-35bea2a2]{opacity:.2;cursor:default}.disabled[data-v-35bea2a2]:hover{cursor:default;opacity:.2}.carousel-3d-dots[data-v-e1ffb936]{z-index:900;pointer-events:none;justify-content:center;gap:8px;width:100%;display:flex;position:absolute;left:0}.carousel-3d-dots--bottom[data-v-e1ffb936]{bottom:14px}.carousel-3d-dots--top[data-v-e1ffb936]{top:14px}.carousel-3d-dot[data-v-e1ffb936]{pointer-events:auto;cursor:pointer;background:#00000059;border:0;border-radius:50%;width:10px;height:10px;padding:0;transition:background-color .2s}.carousel-3d-dot[data-v-e1ffb936]:hover{background:#0000008c}.carousel-3d-dot.is-active[data-v-e1ffb936]{background:#000000d9}.carousel-3d-container[data-v-db4a8480]{z-index:0;touch-action:pan-y;box-sizing:border-box;width:100%;min-height:1px;margin:20px auto;position:relative;overflow:hidden}.carousel-3d-slider[data-v-db4a8480]{transform-style:preserve-3d;perspective:1000px;margin:0 auto;position:relative}
/*$vite$:1*/`)),document.head.appendChild(e)}}catch(t){console.error("vite-plugin-css-injected-by-js",t)}})();
(function(h,i){typeof exports=="object"&&typeof module<"u"?i(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],i):(h=typeof globalThis<"u"?globalThis:h||self,i(h["carousel-3d"]={},h.Vue))})(this,function(h,i){Object.defineProperties(h,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var c=(e,t)=>{const s=e.__vccOpts||e;for(const[a,o]of t)s[a]=o;return s},S={name:"slide",props:{index:{type:Number}},inject:["carousel"],data(){return{styles:{},zIndex:999}},computed:{parent(){return this.carousel},isCurrent(){return this.index===this.parent.currentIndex},shouldRenderContent(){if(!this.parent.lazy)return!0;const e=Math.abs(this.index-this.parent.currentIndex);return Math.min(e,this.parent.total-e)<=Math.max(this.parent.visible+1,3)},slideAriaLabel(){return Number.isInteger(this.index)?`${this.index+1} of ${this.parent.total}`:void 0},leftIndex(){return this.parent.oneDirectional&&this.getSideIndex(this.parent.leftIndices)>this.parent.currentIndex-1?-1:this.getSideIndex(this.parent.leftIndices)},rightIndex(){return this.parent.oneDirectional&&this.getSideIndex(this.parent.rightIndices)>this.parent.total-this.parent.currentIndex-2?-1:this.getSideIndex(this.parent.rightIndices)},slideStyle(){let e={};if(!this.isCurrent){const t=this.leftIndex,s=this.rightIndex;(s>=0||t>=0)&&(e=s>=0?this.calculatePosition(s,!0,this.zIndex):this.calculatePosition(t,!1,this.zIndex),e.opacity=1,e.visibility="visible"),this.parent.hasHiddenSlides&&(this.matchIndex(this.parent.leftOutIndex)?e=this.calculatePosition(this.parent.leftIndices.length-1,!1,this.zIndex):this.matchIndex(this.parent.rightOutIndex)&&(e=this.calculatePosition(this.parent.rightIndices.length-1,!0,this.zIndex)))}return Object.assign(e,{"border-width":this.parent.border+"px",width:this.parent.slideWidth+"px",height:this.parent.slideHeight+"px",transition:" transform "+this.parent.animationSpeed+"ms, opacity "+this.parent.animationSpeed+"ms, visibility "+this.parent.animationSpeed+"ms"})},computedClasses(){return{[`left-${this.leftIndex+1}`]:this.leftIndex>=0,[`right-${this.rightIndex+1}`]:this.rightIndex>=0,current:this.isCurrent}}},methods:{getSideIndex(e){let t=-1;return e.forEach((s,a)=>{this.matchIndex(s)&&(t=a)}),t},matchIndex(e){return e>=0?this.index===e:this.parent.total+e===this.index},calculatePosition(e,t,s){const a=this.parent.disable3d?0:parseInt(this.parent.inverseScaling)+(e+1)*100,o=this.parent.disable3d?0:parseInt(this.parent.perspective),n=this.parent.space==="auto"?parseInt((e+1)*(this.parent.width/1.5),10):parseInt((e+1)*this.parent.space,10),r=this.parent.horizonOffset?parseInt(this.parent.horizonOffset,10)*(e+1):0;return{transform:t?"translateX("+n+"px) translateZ(-"+a+"px) rotateY(-"+o+"deg)"+(r?" translateY("+r+"px)":""):"translateX(-"+n+"px) translateZ(-"+a+"px) rotateY("+o+"deg)"+(r?" translateY("+r+"px)":""),top:this.parent.space==="auto"?0:parseInt((e+1)*this.parent.space),zIndex:s-(Math.abs(e)+1)}},goTo(){if(!this.isCurrent)this.parent.clickable===!0&&this.parent.goFar(this.index);else{const{index:e}=this;this.parent.onMainSlideClick({index:e})}}}},y=["aria-hidden","aria-label"];function w(e,t,s,a,o,n){return(0,i.openBlock)(),(0,i.createElementBlock)("div",{class:(0,i.normalizeClass)(["carousel-3d-slide",n.computedClasses]),style:(0,i.normalizeStyle)(n.slideStyle),onClick:t[0]||(t[0]=r=>n.goTo()),role:"group","aria-roledescription":"slide","aria-hidden":String(!n.isCurrent),"aria-label":n.slideAriaLabel},[n.shouldRenderContent?(0,i.renderSlot)(e.$slots,"default",{index:s.index,isCurrent:n.isCurrent,leftIndex:n.leftIndex,rightIndex:n.rightIndex},void 0,void 0,0):(0,i.createCommentVNode)("",!0)],14,y)}var m=c(S,[["render",w]]);function M(e,t){return e>t?t:e}function g({currentIndex:e,total:t,visible:s,bias:a,dir:o,side:n}){let r=(s-1)/2;const l=n==="left";r=a.toLowerCase()===n?Math.ceil(r):Math.floor(r);const d=[];for(let p=1;p<=r;p++){const j=l&&o==="ltr"||!l&&o!=="ltr";d.push(j?(e+p)%t:(e-p)%t)}return d}function v({currentIndex:e,total:t,visible:s,bias:a,dir:o,side:n}){const r=n==="left";let l=(s-1)/2;return l=(a.toLowerCase()===n?Math.ceil(l):Math.floor(l))+1,r&&o==="ltr"||!r&&o!=="ltr"?t-e-l<=0?-parseInt(t-e-l,10):e+l:e-l}function L(e,t){const s=parseInt(e,10);return!Number.isFinite(s)||s<0||s>=t?0:s}function E(e,t){if(t===0)return 0;const s=Math.max(0,parseInt(e,10)||0);return s>t-1?t-1:s}var b=typeof window<"u",_={props:{autoplay:{type:Boolean,default:!1},autoplayTimeout:{type:Number,default:2e3},autoplayHoverPause:{type:Boolean,default:!0}},data(){return{autoplayInterval:null}},mounted(){b&&(this.autoplayHoverPause&&(this.$el.addEventListener("mouseenter",this.pauseAutoplay),this.$el.addEventListener("mouseleave",this.startAutoplay)),this.startAutoplay())},beforeUnmount(){b&&(this.pauseAutoplay(),this.autoplayHoverPause&&(this.$el.removeEventListener("mouseenter",this.pauseAutoplay),this.$el.removeEventListener("mouseleave",this.startAutoplay)))},methods:{pauseAutoplay(){this.autoplayInterval&&(clearInterval(this.autoplayInterval),this.autoplayInterval=null)},startAutoplay(){this.pauseAutoplay(),this.autoplay&&(this.autoplayInterval=setInterval(()=>{this.dir==="ltr"?this.goPrev():this.goNext()},this.autoplayTimeout))}}},P={name:"controls",props:{width:{type:[String,Number],default:50},height:{type:[String,Number],default:60},prevHtml:{type:String,default:"‹"},nextHtml:{type:String,default:"›"}},inject:["carousel"],computed:{parent(){return this.carousel}}},N={class:"carousel-3d-controls"},C=["disabled"],$=["innerHTML"],O=["disabled"],z=["innerHTML"];function T(e,t,s,a,o,n){return(0,i.openBlock)(),(0,i.createElementBlock)("div",N,[(0,i.createElementVNode)("button",{type:"button",class:(0,i.normalizeClass)(["prev",{disabled:!n.parent.isPrevPossible}]),onClick:t[0]||(t[0]=r=>n.parent.goPrev()),disabled:!n.parent.isPrevPossible,style:(0,i.normalizeStyle)(`width: ${s.width}px; height: ${s.height}px; line-height: ${s.height}px;`),"aria-label":"Previous slide"},[(0,i.renderSlot)(e.$slots,"prev",{goPrev:n.parent.goPrev,disabled:!n.parent.isPrevPossible},()=>[(0,i.createElementVNode)("span",{innerHTML:s.prevHtml},null,8,$)],!0)],14,C),(0,i.createElementVNode)("button",{type:"button",class:(0,i.normalizeClass)(["next",{disabled:!n.parent.isNextPossible}]),onClick:t[1]||(t[1]=r=>n.parent.goNext()),disabled:!n.parent.isNextPossible,style:(0,i.normalizeStyle)(`width: ${s.width}px; height: ${s.height}px; line-height: ${s.height}px;`),"aria-label":"Next slide"},[(0,i.renderSlot)(e.$slots,"next",{goNext:n.parent.goNext,disabled:!n.parent.isNextPossible},()=>[(0,i.createElementVNode)("span",{innerHTML:s.nextHtml},null,8,z)],!0)],14,O)])}var k=c(P,[["render",T],["__scopeId","data-v-35bea2a2"]]),B={name:"carousel-3d-dots",props:{position:{type:String,default:"bottom"}},inject:["carousel"],computed:{parent(){return this.carousel},total(){return this.parent.total},currentIndex(){return this.parent.currentIndex}}},H=["aria-label"],D=["aria-label","aria-current","onClick"];function A(e,t,s,a,o,n){return(0,i.openBlock)(),(0,i.createElementBlock)("div",{class:(0,i.normalizeClass)(["carousel-3d-dots",`carousel-3d-dots--${s.position}`]),role:"group","aria-label":`Slide navigation (${n.total} slides)`},[((0,i.openBlock)(!0),(0,i.createElementBlock)(i.Fragment,null,(0,i.renderList)(n.total,r=>((0,i.openBlock)(),(0,i.createElementBlock)("button",{key:r,type:"button",class:(0,i.normalizeClass)(["carousel-3d-dot",{"is-active":r-1===n.currentIndex}]),"aria-label":`Go to slide ${r} of ${n.total}`,"aria-current":r-1===n.currentIndex?"true":void 0,onClick:l=>n.parent.goSlide(r-1)},null,10,D))),128))],10,H)}var X=c(B,[["render",A],["__scopeId","data-v-e1ffb936"]]),f=typeof window<"u",u=()=>{};function x(e){return e.reduce((t,s)=>s.type===i.Fragment&&Array.isArray(s.children)?t+x(s.children):s.type===i.Comment||s.type===i.Text?t:t+1,0)}var Y={name:"carousel3d",components:{Controls:k,Dots:X},emits:["after-slide-change","before-slide-change","last-slide"],provide(){return{carousel:this}},props:{count:{type:[Number,String],default:0},perspective:{type:[Number,String],default:35},display:{type:[Number,String],default:5},loop:{type:Boolean,default:!0},animationSpeed:{type:[Number,String],default:500},dir:{type:String,default:"rtl"},width:{type:[Number,String],default:360},height:{type:[Number,String],default:270},border:{type:[Number,String],default:1},space:{type:[Number,String],default:"auto"},startIndex:{type:[Number,String],default:0},clickable:{type:Boolean,default:!0},disable3d:{type:Boolean,default:!1},minSwipeDistance:{type:Number,default:10},inverseScaling:{type:[Number,String],default:300},controlsVisible:{type:Boolean,default:!1},controlsPrevHtml:{type:String,default:"‹"},controlsNextHtml:{type:String,default:"›"},controlsWidth:{type:[String,Number],default:50},controlsHeight:{type:[String,Number],default:50},dots:{type:Boolean,default:!1},dotsPosition:{type:String,default:"bottom"},horizonOffset:{type:[Number,String],default:0},lazy:{type:Boolean,default:!1},beforeSlideChange:{type:Function,default:u},onLastSlide:{type:Function,default:u},onSlideChange:{type:Function,default:u},bias:{type:String,default:"left"},onMainSlideClick:{type:Function,default:u},oneDirectional:{type:Boolean,default:!1},ariaLabel:{type:String,default:"3D carousel"}},data(){return{viewport:0,currentIndex:0,total:0,dragOffsetX:0,dragStartX:0,dragOffsetY:0,dragStartY:0,mousedown:!1,zIndex:998,animationTimer:null,navigationTimers:[]}},mixins:[_],watch:{count(){this.computeData()}},created(){this.computeSlideData(!0)},computed:{isLastSlide(){return this.currentIndex===this.total-1},isFirstSlide(){return this.currentIndex===0},isNextPossible(){return this.total>0&&!(!this.loop&&this.isLastSlide)},isPrevPossible(){return this.total>0&&!(!this.loop&&this.isFirstSlide)},slideWidth(){const e=this.viewport,t=parseInt(this.width)+parseInt(this.border,10)*2;return e>0&&e<t&&f?e:t},slideHeight(){const e=parseInt(this.width,10)+parseInt(this.border,10)*2,t=parseInt(parseInt(this.height)+this.border*2,10),s=this.calculateAspectRatio(e,t);return this.slideWidth/s},visible(){return M(this.display,this.total)},hasHiddenSlides(){return this.total>this.visible},leftIndices(){return g({currentIndex:this.currentIndex,total:this.total,visible:this.visible,bias:this.bias,dir:this.dir,side:"left"})},rightIndices(){return g({currentIndex:this.currentIndex,total:this.total,visible:this.visible,bias:this.bias,dir:this.dir,side:"right"})},leftOutIndex(){return v({currentIndex:this.currentIndex,total:this.total,visible:this.visible,bias:this.bias,dir:this.dir,side:"left"})},rightOutIndex(){return v({currentIndex:this.currentIndex,total:this.total,visible:this.visible,bias:this.bias,dir:this.dir,side:"right"})}},methods:{goNext(){this.total>0&&this.isNextPossible&&(this.isLastSlide?this.goSlide(0):this.goSlide(this.currentIndex+1))},goPrev(){this.total>0&&this.isPrevPossible&&(this.isFirstSlide?this.goSlide(this.total-1):this.goSlide(this.currentIndex-1))},goSlide(e){if(this.total<=0)return;const t=L(e,this.total);this.beforeSlideChange!==u&&this.beforeSlideChange(t,this.currentIndex)===!1||(this.currentIndex=t,this.isLastSlide&&(this.onLastSlide!==u&&console.warn("onLastSlide deprecated, please use @last-slide"),this.onLastSlide(this.currentIndex),this.$emit("last-slide",this.currentIndex)),this.$emit("before-slide-change",this.currentIndex),clearTimeout(this.animationTimer),this.animationTimer=setTimeout(()=>{this.animationTimer=null,this.animationEnd()},parseInt(this.animationSpeed,10)))},goFar(e){this.clearNavigationTimers();let t=e===this.total-1&&this.isFirstSlide?-1:e-this.currentIndex;this.isLastSlide&&e===0&&(t=1);const s=t<0?-t:t;let a=0,o=0;for(;o<s;){o+=1;const n=setTimeout(()=>{t<0?this.goPrev():this.goNext()},s===1?0:a);this.navigationTimers.push(n),a+=this.animationSpeed/s}},clearNavigationTimers(){this.navigationTimers.forEach(e=>clearTimeout(e)),this.navigationTimers=[]},animationEnd(){this.onSlideChange!==u&&console.warn("onSlideChange deprecated, please use @after-slide-change"),this.onSlideChange(this.currentIndex),this.$emit("after-slide-change",this.currentIndex)},handleMouseup(){this.mousedown=!1,this.dragOffsetX=0,this.dragOffsetY=0},handleMousedown(e){!e.touches&&e.cancelable&&e.preventDefault();const t=this.getEventPoint(e);t&&(this.mousedown=!0,this.dragStartX=t.clientX,this.dragStartY=t.clientY)},handleMousemove(e){if(!this.mousedown)return;const t=this.getEventPoint(e);if(!t)return;const s=t.clientX,a=t.clientY,o=this.dragStartX-s,n=this.dragStartY-a;this.dragOffsetX=o,this.dragOffsetY=n,!(Math.abs(this.dragOffsetY)>Math.abs(this.dragOffsetX))&&(this.dragOffsetX>this.minSwipeDistance?(this.handleMouseup(),this.goNext()):this.dragOffsetX<-this.minSwipeDistance&&(this.handleMouseup(),this.goPrev()))},getEventPoint(e){return e.touches&&e.touches[0]||e.changedTouches&&e.changedTouches[0]||e},addInteractionListeners(){if(window.PointerEvent){this.$el.addEventListener("pointerdown",this.handleMousedown),this.$el.addEventListener("pointerup",this.handleMouseup),this.$el.addEventListener("pointercancel",this.handleMouseup),this.$el.addEventListener("pointerleave",this.handleMouseup),this.$el.addEventListener("pointermove",this.handleMousemove);return}this.$el.addEventListener("touchstart",this.handleMousedown),this.$el.addEventListener("touchend",this.handleMouseup),this.$el.addEventListener("touchcancel",this.handleMouseup),this.$el.addEventListener("touchmove",this.handleMousemove),this.$el.addEventListener("mousedown",this.handleMousedown),this.$el.addEventListener("mouseup",this.handleMouseup),this.$el.addEventListener("mouseleave",this.handleMouseup),this.$el.addEventListener("mousemove",this.handleMousemove)},removeInteractionListeners(){if(window.PointerEvent){this.$el.removeEventListener("pointerdown",this.handleMousedown),this.$el.removeEventListener("pointerup",this.handleMouseup),this.$el.removeEventListener("pointercancel",this.handleMouseup),this.$el.removeEventListener("pointerleave",this.handleMouseup),this.$el.removeEventListener("pointermove",this.handleMousemove);return}this.$el.removeEventListener("touchstart",this.handleMousedown),this.$el.removeEventListener("touchend",this.handleMouseup),this.$el.removeEventListener("touchcancel",this.handleMouseup),this.$el.removeEventListener("touchmove",this.handleMousemove),this.$el.removeEventListener("mousedown",this.handleMousedown),this.$el.removeEventListener("mouseup",this.handleMouseup),this.$el.removeEventListener("mouseleave",this.handleMouseup),this.$el.removeEventListener("mousemove",this.handleMousemove)},attachMutationObserver(){const e=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;if(e){const t={childList:!0,characterData:!0,subtree:!0};this.mutationObserver=new e(()=>{this.$nextTick(()=>{this.computeData()})}),this.$el&&this.mutationObserver.observe(this.$el,t)}},detachMutationObserver(){this.mutationObserver&&this.mutationObserver.disconnect()},getSlideCount(){const e=this.$slots.default;return e?x(e()):0},calculateAspectRatio(e,t){return Math.min(e/t)},computeSlideData(e){if(this.total=this.getSlideCount(),this.total===0){this.currentIndex=0;return}(e||this.currentIndex>=this.total)&&(this.currentIndex=E(this.startIndex,this.total))},computeData(e){this.computeSlideData(e),this.viewport=this.$el.clientWidth},setSize(){this.viewport=this.$el.clientWidth,this.$el.style.height=this.slideHeight+"px";const e=this.$el.querySelector(".carousel-3d-slider");e&&(e.style.width=this.slideWidth+"px",e.style.height=this.slideHeight+"px")}},mounted(){f&&(this.computeData(!0),this.attachMutationObserver(),window.addEventListener("resize",this.setSize),this.addInteractionListeners())},beforeUnmount(){f&&(this.detachMutationObserver(),this.removeInteractionListeners(),window.removeEventListener("resize",this.setSize)),clearTimeout(this.animationTimer),this.clearNavigationTimers()}},F=["aria-label"];function V(e,t,s,a,o,n){const r=(0,i.resolveComponent)("controls"),l=(0,i.resolveComponent)("dots");return(0,i.openBlock)(),(0,i.createElementBlock)("div",{class:"carousel-3d-container",style:(0,i.normalizeStyle)({height:n.slideHeight+"px"}),role:"region","aria-roledescription":"carousel","aria-label":s.ariaLabel,tabindex:"0",onKeydown:[t[0]||(t[0]=(0,i.withKeys)((0,i.withModifiers)((...d)=>n.goPrev&&n.goPrev(...d),["prevent"]),["left"])),t[1]||(t[1]=(0,i.withKeys)((0,i.withModifiers)((...d)=>n.goNext&&n.goNext(...d),["prevent"]),["right"]))]},[(0,i.createElementVNode)("div",{class:"carousel-3d-slider",style:(0,i.normalizeStyle)({width:n.slideWidth+"px",height:n.slideHeight+"px"})},[(0,i.renderSlot)(e.$slots,"default",{},void 0,!0)],4),s.controlsVisible?((0,i.openBlock)(),(0,i.createBlock)(r,{key:0,"next-html":s.controlsNextHtml,"prev-html":s.controlsPrevHtml,width:s.controlsWidth,height:s.controlsHeight},{prev:(0,i.withCtx)(d=>[(0,i.renderSlot)(e.$slots,"prev",(0,i.normalizeProps)((0,i.guardReactiveProps)(d)),void 0,!0)]),next:(0,i.withCtx)(d=>[(0,i.renderSlot)(e.$slots,"next",(0,i.normalizeProps)((0,i.guardReactiveProps)(d)),void 0,!0)]),_:3},8,["next-html","prev-html","width","height"])):(0,i.createCommentVNode)("",!0),s.dots?((0,i.openBlock)(),(0,i.createBlock)(l,{key:1,position:s.dotsPosition},null,8,["position"])):(0,i.createCommentVNode)("",!0)],44,F)}var I=c(Y,[["render",V],["__scopeId","data-v-db4a8480"]]),W=e=>{e.component("carousel3d",I),e.component("slide",m)},R={install:W};h.Carousel3d=I,h.Slide=m,h.default=R});
//# sourceMappingURL=carousel-3d.umd.min.js.map