/*! vue-carousel v2.0.0 | (c) 2018-present Chen Fengyuan | MIT */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('vue')) : typeof define === 'function' && define.amd ? define(['vue'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.VueCarousel = factory(global.Vue)); })(this, (function (vue) { 'use strict'; const IS_BROWSER = typeof window !== 'undefined' && typeof window.document !== 'undefined'; const IS_TOUCH_DEVICE = IS_BROWSER && window.document.documentElement ? 'ontouchstart' in window.document.documentElement : false; const HAS_POINTER_EVENT = IS_BROWSER ? 'PointerEvent' in window : false; const ON_TOUCH_START = IS_TOUCH_DEVICE ? 'ontouchstart' : 'onmousedown'; const ON_TOUCH_MOVE = IS_TOUCH_DEVICE ? 'ontouchmove' : 'onmousemove'; const ON_TOUCH_END = IS_TOUCH_DEVICE ? 'ontouchend' : 'onmouseup'; const ON_POINTER_DOWN = HAS_POINTER_EVENT ? 'onpointerdown' : ON_TOUCH_START; const ON_POINTER_MOVE = HAS_POINTER_EVENT ? 'onpointermove' : ON_TOUCH_MOVE; const ON_POINTER_UP = HAS_POINTER_EVENT ? 'onpointerup' : ON_TOUCH_END; const ON_POINTER_ENTER = HAS_POINTER_EVENT ? 'onpointerenter' : 'onmouseenter'; const ON_POINTER_LEAVE = HAS_POINTER_EVENT ? 'onpointerleave' : 'onmouseleave'; const createVueComponent = (content) => { if ((typeof content === 'object' && content !== null) || typeof content === 'function') { return content; } return { template: String(content), }; }; var script = vue.defineComponent({ name: 'VueCarousel', props: { autoplay: { type: Boolean, default: true, }, controls: { type: [Boolean, String], default: 'hover', }, data: { type: Array, default: undefined, }, direction: { type: String, default: 'left', }, duration: { type: Number, default: 600, }, indicators: { type: [Boolean, String], default: true, }, indicatorTrigger: { type: String, default: 'click', }, indicatorType: { type: String, default: 'line', }, interval: { type: Number, default: 5000, }, pauseOnEnter: { type: Boolean, default: true, }, slideOnSwipe: { type: Boolean, default: true, }, tag: { type: String, default: 'div', }, }, emits: ['slide', 'slid'], data() { return { endX: 0, endY: 0, index: 0, list: [], onVisibilityChange: () => { }, playing: false, sliding: false, startX: 0, startY: 0, timeout: 0, }; }, watch: { data() { this.init(); }, }, created() { this.init(); }, mounted() { document.addEventListener('visibilitychange', this.onVisibilityChange = () => { if (this.playing) { if (document.visibilityState === 'visible') { this.cycle(); } else { this.pause(); } } }); if (this.autoplay) { this.play(); } }, beforeUnmount() { document.removeEventListener('visibilitychange', this.onVisibilityChange); }, methods: { init() { const { data } = this; const list = []; if (data && data.length > 0) { const maxIndex = data.length - 1; // In case the number of the data list is reduced (#23). if (this.index > maxIndex) { this.index = maxIndex; } data.forEach((rawItem, index) => { const active = index === this.index; const item = { ...(rawItem && rawItem.content !== undefined ? rawItem : { content: rawItem, }), active, bottom: false, left: false, raw: rawItem, right: false, sliding: active, toBottom: false, toLeft: false, toRight: false, toTop: false, top: false, }; list.push(item); }); } this.list = list; }, play() { if (!this.playing) { this.playing = true; this.cycle(); } }, cycle() { if (this.playing) { this.pause(); this.timeout = window.setTimeout(() => { this.next(() => { this.cycle(); }); }, this.interval); } }, pause() { window.clearTimeout(this.timeout); this.timeout = 0; }, stop() { if (this.playing) { this.pause(); this.playing = false; } }, prev(done) { this.slideTo(this.index - 1, done); }, next(done) { this.slideTo(this.index + 1, done); }, slide(index, reverse = false, done = () => { }) { if (document.hidden || this.sliding) { done(); return; } const { list } = this; const minIndex = 0; const maxIndex = list.length - 1; if (index > maxIndex) { index = minIndex; } else if (index < minIndex) { index = maxIndex; } if (index === this.index) { done(); return; } this.sliding = true; this.$emit('slide', index, this.index); const active = list[this.index]; const next = list[index]; switch (this.direction) { case 'up': next.bottom = !reverse; next.top = reverse; break; case 'right': next.left = !reverse; next.right = reverse; break; case 'down': next.top = !reverse; next.bottom = reverse; break; // case 'left': default: next.right = !reverse; next.left = reverse; } // Waiting for the class change applied vue.nextTick(() => { // Force reflow to enable CSS3 transition // eslint-disable-next-line this.$el.offsetWidth; switch (this.direction) { case 'up': active.toTop = !reverse; active.toBottom = reverse; next.toTop = !reverse; next.toBottom = reverse; break; case 'right': active.toRight = !reverse; active.toLeft = reverse; next.toRight = !reverse; next.toLeft = reverse; break; case 'down': active.toBottom = !reverse; active.toTop = reverse; next.toBottom = !reverse; next.toTop = reverse; break; // case 'left': default: active.toLeft = !reverse; active.toRight = reverse; next.toLeft = !reverse; next.toRight = reverse; } active.sliding = false; next.sliding = true; setTimeout(() => { active.active = false; active.top = false; active.right = false; active.bottom = false; active.left = false; active.toTop = false; active.toRight = false; active.toBottom = false; active.toLeft = false; next.active = true; next.top = false; next.right = false; next.bottom = false; next.left = false; next.toTop = false; next.toRight = false; next.toBottom = false; next.toLeft = false; this.$emit('slid', index, this.index); this.index = index; this.sliding = false; done(); }, this.duration); }); }, slideTo(index, done) { if (index === this.index) { return; } this.slide(index, index < this.index, done); }, slideStart(event) { const touch = event.touches ? event.touches[0] : null; if (this.playing && this.pauseOnEnter) { this.stop(); } this.startX = touch ? touch.pageX : event.pageX; this.startY = touch ? touch.pageY : event.pageY; }, slideMove(event) { const touch = event.touches ? event.touches[0] : null; event.preventDefault(); this.endX = touch ? touch.pageX : event.pageX; this.endY = touch ? touch.pageY : event.pageY; }, slideEnd() { const moveX = this.endX - this.startX; const moveY = this.endY - this.startY; this.endX = this.startX; this.endY = this.startY; // Ignore click events if (moveX === 0 && moveY === 0) { return; } const thresholdX = this.$el.offsetWidth / 5; const thresholdY = this.$el.offsetHeight / 5; const top = moveY < -thresholdY; const right = moveX > thresholdX; const bottom = moveY > thresholdY; const left = moveX < -thresholdX; const done = () => { if (!this.playing && this.pauseOnEnter) { this.play(); } }; let prev = false; let next = false; switch (this.direction) { case 'up': prev = bottom; next = top; break; case 'right': prev = left; next = right; break; case 'down': prev = top; next = bottom; break; // case 'left': default: prev = right; next = left; } if (prev) { this.prev(done); } else if (next) { this.next(done); } else { done(); } }, }, render() { return vue.h(this.tag, { class: { 'vue-carousel': true, [`vue-carousel--${this.direction}`]: this.direction, 'vue-carousel--slidable': this.slideOnSwipe, 'vue-carousel--controls': this.controls === 'hover', 'vue-carousel--indicators': this.indicators === 'hover', }, ...(this.pauseOnEnter ? { [ON_POINTER_ENTER]: this.pause, [ON_POINTER_LEAVE]: this.cycle, } : {}), ...(this.slideOnSwipe ? { [ON_POINTER_DOWN]: this.slideStart, [ON_POINTER_MOVE]: this.slideMove, [ON_POINTER_UP]: this.slideEnd, } : {}), }, this.list.length === 0 ? [] : [ vue.h('ul', { class: 'vue-carousel__list', }, this.list.map((item, index) => vue.h('li', { 'data-index': index, class: { 'vue-carousel__item': true, 'vue-carousel__item--active': item.active, 'vue-carousel__item--top': item.top, 'vue-carousel__item--right': item.right, 'vue-carousel__item--bottom': item.bottom, 'vue-carousel__item--left': item.left, 'vue-carousel__item--to-top': item.toTop, 'vue-carousel__item--to-right': item.toRight, 'vue-carousel__item--to-bottom': item.toBottom, 'vue-carousel__item--to-left': item.toLeft, }, style: { 'transition-duration': `${this.duration / 1000}s`, }, }, [ vue.h(createVueComponent(item.content)), ]))), this.indicators ? vue.h('ol', { class: { 'vue-carousel__indicators': true, [`vue-carousel__indicators--${this.indicatorType}`]: this.indicatorType, }, }, this.list.map((item, index) => vue.h('li', { 'data-slide-to': index, class: { 'vue-carousel__indicator': true, 'vue-carousel__indicator--active': item.sliding, }, ...(() => { const listeners = {}; const slide = () => { this.slideTo(index); }; if (this.indicatorTrigger === 'hover') { listeners[ON_POINTER_ENTER] = slide; if (IS_TOUCH_DEVICE && !HAS_POINTER_EVENT) { listeners[ON_TOUCH_START] = slide; } } else { listeners.onclick = slide; } return listeners; })(), }))) : '', this.controls ? vue.h('button', { type: 'button', 'data-slide': 'prev', class: 'vue-carousel__control vue-carousel__control--prev', onclick: () => { if (['right', 'down'].indexOf(this.direction) > -1) { this.next(); } else { this.prev(); } }, }) : '', this.controls ? vue.h('button', { type: 'button', 'data-slide': 'next', class: 'vue-carousel__control vue-carousel__control--next', onclick: () => { if (['right', 'down'].indexOf(this.direction) > -1) { this.prev(); } else { this.next(); } }, }) : '', ]); }, }); 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 = ".vue-carousel{position:relative;user-select:none}.vue-carousel--slidable{touch-action:none}.vue-carousel--down>.vue-carousel__indicators,.vue-carousel--up>.vue-carousel__indicators{bottom:auto;flex-direction:column;left:auto;right:0;top:50%;transform:translateY(-50%)}.vue-carousel--down>.vue-carousel__indicators>.vue-carousel__indicator:before,.vue-carousel--up>.vue-carousel__indicators>.vue-carousel__indicator:before{height:100%;width:.125rem}.vue-carousel--down>.vue-carousel__indicators--disc>.vue-carousel__indicator,.vue-carousel--up>.vue-carousel__indicators--disc>.vue-carousel__indicator{height:.75rem;width:1.5rem}.vue-carousel--down>.vue-carousel__indicators--disc>.vue-carousel__indicator:before,.vue-carousel--up>.vue-carousel__indicators--disc>.vue-carousel__indicator:before{height:.5rem;width:.5rem}.vue-carousel--right>.vue-carousel__indicators{flex-direction:row-reverse}.vue-carousel--down>.vue-carousel__indicators{flex-direction:column-reverse}.vue-carousel--controls:hover>.vue-carousel__control{opacity:.5;transform:translateX(0);z-index:1}.vue-carousel--controls:hover>.vue-carousel__control:focus,.vue-carousel--controls:hover>.vue-carousel__control:hover{opacity:1}.vue-carousel--controls>.vue-carousel__control{opacity:0;z-index:-1}.vue-carousel--controls>.vue-carousel__control--prev{transform:translateX(-50%)}.vue-carousel--controls>.vue-carousel__control--next{transform:translateX(50%)}.vue-carousel--indicators:hover>.vue-carousel__indicators{opacity:1;z-index:1}.vue-carousel--indicators>.vue-carousel__indicators{opacity:0;transition:opacity .15s;z-index:-1}.vue-carousel__list{margin:0;overflow:hidden;padding:0;position:relative;width:100%}.vue-carousel__item{display:none;margin:0}.vue-carousel__item--active,.vue-carousel__item--bottom,.vue-carousel__item--left,.vue-carousel__item--right,.vue-carousel__item--top{display:block;transition:transform .6s ease-in-out;width:100%}.vue-carousel__item--bottom,.vue-carousel__item--left,.vue-carousel__item--right,.vue-carousel__item--top{left:0;position:absolute;top:0}.vue-carousel__item--top{transform:translateY(-100%)}.vue-carousel__item--top.vue-carousel__item--to-bottom{transform:translateY(0)}.vue-carousel__item--right{transform:translateX(100%)}.vue-carousel__item--right.vue-carousel__item--to-left{transform:translateX(0)}.vue-carousel__item--bottom{transform:translateY(100%)}.vue-carousel__item--bottom.vue-carousel__item--to-top{transform:translateY(0)}.vue-carousel__item--left{transform:translateX(-100%)}.vue-carousel__item--left.vue-carousel__item--to-right{transform:translateX(0)}.vue-carousel__item--active{transform:translate(0);z-index:1}.vue-carousel__item--active.vue-carousel__item--to-top{transform:translateY(-100%)}.vue-carousel__item--active.vue-carousel__item--to-right{transform:translateX(100%)}.vue-carousel__item--active.vue-carousel__item--to-bottom{transform:translateY(100%)}.vue-carousel__item--active.vue-carousel__item--to-left{transform:translateX(-100%)}.vue-carousel__indicators{bottom:0;display:flex;justify-content:center;left:50%;list-style:none;margin:0;padding:0;position:absolute;transform:translateX(-50%);z-index:1}.vue-carousel__indicators--disc>.vue-carousel__indicator{width:.75rem}.vue-carousel__indicators--disc>.vue-carousel__indicator:before{border-radius:50%;height:.5rem;width:.5rem}.vue-carousel__indicator{cursor:pointer;height:1.5rem;margin:.125rem;opacity:.5;position:relative;transition:opacity .15s;width:1.5rem}.vue-carousel__indicator:before{background-color:#fff;content:\"\";display:block;height:.125rem;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:100%}.vue-carousel__indicator--active{opacity:1}.vue-carousel__control{background-color:rgba(0,0,0,.5);border:0;border-radius:50%;color:#fff;cursor:pointer;height:2rem;margin-top:-1rem;opacity:.5;padding:.5rem;position:absolute;top:50%;transition:all .15s;width:2rem}.vue-carousel__control:focus,.vue-carousel__control:hover{opacity:1}.vue-carousel__control:focus{outline:none}.vue-carousel__control:before{border:.0625rem solid transparent;border-radius:.125rem;content:\"\";display:block;height:.5rem;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%) rotate(45deg);width:.5rem}.vue-carousel__control--prev{left:1rem}.vue-carousel__control--prev:before{border-bottom-color:#fff;border-left-color:#fff;margin-left:.125rem}.vue-carousel__control--next{right:1rem}.vue-carousel__control--next:before{border-right-color:#fff;border-top-color:#fff;margin-left:-.125rem}"; styleInject(css_248z); return script; }));