123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 |
- /*! 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;
- }));
|