various-ui
Version:
This is a test version of the Vue 3 component library
211 lines (208 loc) • 8.16 kB
JavaScript
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