UNPKG

various-ui

Version:

This is a test version of the Vue 3 component library

211 lines (208 loc) 8.16 kB
import { gsap } from 'gsap'; import { ref, watch, computed } from 'vue'; import '../../../../utils/index.mjs'; import { isNumber } from 'lodash-es'; const useComposable = (define, emits) => { const variable = { delay: define.transitionDelay / 1e3, observer: void 0 }; const refs = { main: ref(), //* 轮播图组件的主体 container: ref(), //* 轮播图组件列表的容器 childrens: ref([]), //* 轮播图组件列表 autoTimer: ref(), //* 轮播图组件自动播放定时器 skipTimer: ref(false), //* 轮播图组件是否正在跳转中 active: ref(0) //* 轮播图组件当前激活的列表项 }; const utils = { //* 切换动画 switch: (current, ready, option) => { var _a, _b; if (!refs.container.value || !((_a = refs.childrens.value) == null ? void 0 : _a[current]) || !((_b = refs.childrens.value) == null ? void 0 : _b[ready])) return; else { refs.active.value = ready; } !(option == null ? void 0 : option.notEmit) && emits("change", refs.active.value); const currentNode = refs.childrens.value[current]; const readyNode = refs.childrens.value[ready]; const size = refs.container.value.clientWidth; if (option == null ? void 0 : option.set) { gsap.set(readyNode, { translateX: (option == null ? void 0 : option.next) ? `${-2 * size}px` : 0 }); } const timeline = gsap.timeline(); const leave = { position: "absolute", duration: variable.delay, translateX: (option == null ? void 0 : option.next) ? 0 : `${-2 * size}px`, onComplete: () => { gsap.set(currentNode, { translateX: 0 }); timeline.kill(); if (define.autoplay) { refs.autoTimer.value = setTimeout(() => methods.switchCarousel(refs.active.value + 1), define.delay); } refs.skipTimer.value = false; !(option == null ? void 0 : option.notEmit) && emits("change-after", refs.active.value); } }; timeline.to(readyNode, { position: "relative", duration: variable.delay, translateX: `${-1 * size}px` }); timeline.to(currentNode, leave, "<"); }, //* 自动播放回调 autoplayHandler: () => { refs.autoTimer.value && clearTimeout(refs.autoTimer.value); refs.autoTimer.value = setTimeout(() => { refs.autoTimer.value = void 0; if (define.autoplay) { methods.switchCarousel(refs.active.value + 1); } }, define.delay); } }; const watchs = { stopAutoPlay: watch(() => define.autoplay, utils.autoplayHandler, { immediate: true }) }; const methods = { //* 初始化函数 init: (number) => { var _a, _b; if (!refs.container.value || !((_b = (_a = refs.container.value) == null ? void 0 : _a.children) == null ? void 0 : _b.length)) return; else { refs.childrens.value = []; for (let i = 0; i < refs.container.value.children.length; i++) { const node = refs.container.value.children[i]; gsap.set(node, { translateX: 0, position: "absolute" }); refs.childrens.value.push(node); } if (isNumber(number)) refs.active.value = number; if (refs.childrens.value[refs.active.value]) { gsap.set(refs.childrens.value[refs.active.value], { translateX: `${-1 * refs.container.value.clientWidth}px`, position: "relative" }); } } }, //* 拖拽函数 dragCarousel: (ev) => { var _a; const count = refs.childrens.value.length || 0; if (!refs.container.value || refs.skipTimer.value || count <= 1) return; refs.autoTimer.value && clearTimeout(refs.autoTimer.value); refs.skipTimer.value = true; const initPos = ev.touches[0].clientX; const size = ((_a = refs.container.value) == null ? void 0 : _a.clientWidth) || 0; const option = { next: 1, //* 拖拽方向[1 = 左, -1 = 右], ready: -1, //* 候场的HTML NODE Key offset: 0, //* 拖拽距离 current: refs.active.value //* 退场的HTML NODE Key }; const ontouchmove = (ev2) => { ev2.preventDefault(); option.next = ev2.touches[0].clientX < initPos ? -1 : 1; option.offset = ev2.touches[0].clientX - initPos; if (Math.abs(option.offset) > size) option.offset = size * option.next; if (ev2.touches[0].clientX > initPos && refs.active.value == 0) { option.ready = count - 1; } else if (ev2.touches[0].clientX < initPos && refs.active.value == count - 1) { option.ready = 0; } else { option.ready = refs.active.value - option.next; } if (refs.childrens.value[option.current] && refs.childrens.value[option.ready]) { gsap.set(refs.childrens.value[option.current], { translateX: `${option.offset + -1 * size}px` }); gsap.set(refs.childrens.value[option.ready], { translateX: `${option.offset + (option.next > 0 ? -2 * size : 0)}px` }); } }; const ontouchend = (ev2) => { document.body.removeEventListener("touchmove", ontouchmove); document.body.removeEventListener("touchend", ontouchend); emits("drag"); if (option.offset != 0) { if (Math.abs(option.offset) <= size * 0.3) { utils.switch(option.ready, option.current, { next: option.next < 0, notEmit: true }); } else { utils.switch(option.current, option.ready, { next: option.next > 0 }); } } else { refs.skipTimer.value = false; if (define.autoplay) { refs.autoTimer.value = setTimeout(() => methods.switchCarousel(refs.active.value + 1), define.delay); } } }; emits("drag-after"); document.body.addEventListener("touchmove", ontouchmove, { passive: false }); document.body.addEventListener("touchend", ontouchend); }, //* 切换函数 switchCarousel: (number, _data) => { const count = refs.childrens.value.length || 0; if (!refs.container.value || refs.skipTimer.value || count <= 1 || number == refs.active.value) return; else { refs.autoTimer.value && clearTimeout(refs.autoTimer.value); refs.skipTimer.value = true; if (number >= count || number < 0) { if (number >= count) { utils.switch(refs.active.value, 0, { set: true }); } else if (number < 0) { utils.switch(refs.active.value, count - 1, { set: true, next: true }); } } else { utils.switch(refs.active.value, number, { set: true, next: refs.active.value > number }); } } }, //* 切换函数(上) switchBack: () => methods.switchCarousel(refs.active.value - 1), //* 切换函数(下) switchNext: () => methods.switchCarousel(refs.active.value + 1) }; const computeds = { //* 是否显示左侧控制按钮 isFirstControl: computed(() => define.arrow != "never"), //* 是否显示右侧控制按钮 isLastControl: computed(() => define.arrow != "never"), //* 主体类名 className: computed(() => `ui-carousel-${define.arrow}`), style: computed(() => { const result = {}; if (define.width) { if (isNumber(define.width)) result.width = define.width + "px"; else result.width = define.width; } if (define.height) { if (isNumber(define.height)) result.height = define.height + "px"; else result.height = define.height; } return result; }) }; const ons = { //* 容器的处理函数 container: define.drag ? { touchstart: methods.dragCarousel } : {}, //* 主体的处理函数 main: { mouseenter: () => refs.autoTimer.value && clearTimeout(refs.autoTimer.value), mouseleave: () => { utils.autoplayHandler(); } } }; return { ons, refs, watchs, methods, computeds, variable }; }; export { useComposable }; //# sourceMappingURL=composable.mjs.map