123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- var __defProp = Object.defineProperty;
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
- var __getOwnPropNames = Object.getOwnPropertyNames;
- var __hasOwnProp = Object.prototype.hasOwnProperty;
- var __export = (target, all) => {
- for (var name2 in all)
- __defProp(target, name2, { get: all[name2], enumerable: true });
- };
- var __copyProps = (to, from, except, desc) => {
- if (from && typeof from === "object" || typeof from === "function") {
- for (let key of __getOwnPropNames(from))
- if (!__hasOwnProp.call(to, key) && key !== except)
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
- }
- return to;
- };
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
- var stdin_exports = {};
- __export(stdin_exports, {
- SWIPE_KEY: () => SWIPE_KEY,
- default: () => stdin_default
- });
- module.exports = __toCommonJS(stdin_exports);
- var import_vue = require("vue");
- var import_vue2 = require("vue");
- var import_utils = require("../utils");
- var import_use = require("@vant/use");
- var import_use_touch = require("../composables/use-touch");
- var import_use_expose = require("../composables/use-expose");
- var import_on_popup_reopen = require("../composables/on-popup-reopen");
- const [name, bem] = (0, import_utils.createNamespace)("swipe");
- const swipeProps = {
- loop: import_utils.truthProp,
- width: import_utils.numericProp,
- height: import_utils.numericProp,
- vertical: Boolean,
- autoplay: (0, import_utils.makeNumericProp)(0),
- duration: (0, import_utils.makeNumericProp)(500),
- touchable: import_utils.truthProp,
- lazyRender: Boolean,
- initialSwipe: (0, import_utils.makeNumericProp)(0),
- indicatorColor: String,
- showIndicators: import_utils.truthProp,
- stopPropagation: import_utils.truthProp
- };
- const SWIPE_KEY = Symbol(name);
- var stdin_default = (0, import_vue2.defineComponent)({
- name,
- props: swipeProps,
- emits: ["change"],
- setup(props, {
- emit,
- slots
- }) {
- const root = (0, import_vue2.ref)();
- const track = (0, import_vue2.ref)();
- const state = (0, import_vue2.reactive)({
- rect: null,
- width: 0,
- height: 0,
- offset: 0,
- active: 0,
- swiping: false
- });
- const touch = (0, import_use_touch.useTouch)();
- const {
- children,
- linkChildren
- } = (0, import_use.useChildren)(SWIPE_KEY);
- const count = (0, import_vue2.computed)(() => children.length);
- const size = (0, import_vue2.computed)(() => state[props.vertical ? "height" : "width"]);
- const delta = (0, import_vue2.computed)(() => props.vertical ? touch.deltaY.value : touch.deltaX.value);
- const minOffset = (0, import_vue2.computed)(() => {
- if (state.rect) {
- const base = props.vertical ? state.rect.height : state.rect.width;
- return base - size.value * count.value;
- }
- return 0;
- });
- const maxCount = (0, import_vue2.computed)(() => Math.ceil(Math.abs(minOffset.value) / size.value));
- const trackSize = (0, import_vue2.computed)(() => count.value * size.value);
- const activeIndicator = (0, import_vue2.computed)(() => (state.active + count.value) % count.value);
- const isCorrectDirection = (0, import_vue2.computed)(() => {
- const expect = props.vertical ? "vertical" : "horizontal";
- return touch.direction.value === expect;
- });
- const trackStyle = (0, import_vue2.computed)(() => {
- const style = {
- transitionDuration: `${state.swiping ? 0 : props.duration}ms`,
- transform: `translate${props.vertical ? "Y" : "X"}(${state.offset}px)`
- };
- if (size.value) {
- const mainAxis = props.vertical ? "height" : "width";
- const crossAxis = props.vertical ? "width" : "height";
- style[mainAxis] = `${trackSize.value}px`;
- style[crossAxis] = props[crossAxis] ? `${props[crossAxis]}px` : "";
- }
- return style;
- });
- const getTargetActive = (pace) => {
- const {
- active
- } = state;
- if (pace) {
- if (props.loop) {
- return (0, import_utils.clamp)(active + pace, -1, count.value);
- }
- return (0, import_utils.clamp)(active + pace, 0, maxCount.value);
- }
- return active;
- };
- const getTargetOffset = (targetActive, offset = 0) => {
- let currentPosition = targetActive * size.value;
- if (!props.loop) {
- currentPosition = Math.min(currentPosition, -minOffset.value);
- }
- let targetOffset = offset - currentPosition;
- if (!props.loop) {
- targetOffset = (0, import_utils.clamp)(targetOffset, minOffset.value, 0);
- }
- return targetOffset;
- };
- const move = ({
- pace = 0,
- offset = 0,
- emitChange
- }) => {
- if (count.value <= 1) {
- return;
- }
- const {
- active
- } = state;
- const targetActive = getTargetActive(pace);
- const targetOffset = getTargetOffset(targetActive, offset);
- if (props.loop) {
- if (children[0] && targetOffset !== minOffset.value) {
- const outRightBound = targetOffset < minOffset.value;
- children[0].setOffset(outRightBound ? trackSize.value : 0);
- }
- if (children[count.value - 1] && targetOffset !== 0) {
- const outLeftBound = targetOffset > 0;
- children[count.value - 1].setOffset(outLeftBound ? -trackSize.value : 0);
- }
- }
- state.active = targetActive;
- state.offset = targetOffset;
- if (emitChange && targetActive !== active) {
- emit("change", activeIndicator.value);
- }
- };
- const correctPosition = () => {
- state.swiping = true;
- if (state.active <= -1) {
- move({
- pace: count.value
- });
- } else if (state.active >= count.value) {
- move({
- pace: -count.value
- });
- }
- };
- const prev = () => {
- correctPosition();
- touch.reset();
- (0, import_use.doubleRaf)(() => {
- state.swiping = false;
- move({
- pace: -1,
- emitChange: true
- });
- });
- };
- const next = () => {
- correctPosition();
- touch.reset();
- (0, import_use.doubleRaf)(() => {
- state.swiping = false;
- move({
- pace: 1,
- emitChange: true
- });
- });
- };
- let autoplayTimer;
- const stopAutoplay = () => clearTimeout(autoplayTimer);
- const autoplay = () => {
- stopAutoplay();
- if (props.autoplay > 0 && count.value > 1) {
- autoplayTimer = setTimeout(() => {
- next();
- autoplay();
- }, +props.autoplay);
- }
- };
- const initialize = (active = +props.initialSwipe) => {
- if (!root.value) {
- return;
- }
- const cb = () => {
- var _a, _b;
- if (!(0, import_utils.isHidden)(root)) {
- const rect = {
- width: root.value.offsetWidth,
- height: root.value.offsetHeight
- };
- state.rect = rect;
- state.width = +((_a = props.width) != null ? _a : rect.width);
- state.height = +((_b = props.height) != null ? _b : rect.height);
- }
- if (count.value) {
- active = Math.min(count.value - 1, active);
- }
- state.active = active;
- state.swiping = true;
- state.offset = getTargetOffset(active);
- children.forEach((swipe) => {
- swipe.setOffset(0);
- });
- autoplay();
- };
- if ((0, import_utils.isHidden)(root)) {
- (0, import_vue2.nextTick)().then(cb);
- } else {
- cb();
- }
- };
- const resize = () => initialize(state.active);
- let touchStartTime;
- const onTouchStart = (event) => {
- if (!props.touchable)
- return;
- touch.start(event);
- touchStartTime = Date.now();
- stopAutoplay();
- correctPosition();
- };
- const onTouchMove = (event) => {
- if (props.touchable && state.swiping) {
- touch.move(event);
- if (isCorrectDirection.value) {
- const isEdgeTouch = !props.loop && (state.active === 0 && delta.value > 0 || state.active === count.value - 1 && delta.value < 0);
- if (!isEdgeTouch) {
- (0, import_utils.preventDefault)(event, props.stopPropagation);
- move({
- offset: delta.value
- });
- }
- }
- }
- };
- const onTouchEnd = () => {
- if (!props.touchable || !state.swiping) {
- return;
- }
- const duration = Date.now() - touchStartTime;
- const speed = delta.value / duration;
- const shouldSwipe = Math.abs(speed) > 0.25 || Math.abs(delta.value) > size.value / 2;
- if (shouldSwipe && isCorrectDirection.value) {
- const offset = props.vertical ? touch.offsetY.value : touch.offsetX.value;
- let pace = 0;
- if (props.loop) {
- pace = offset > 0 ? delta.value > 0 ? -1 : 1 : 0;
- } else {
- pace = -Math[delta.value > 0 ? "ceil" : "floor"](delta.value / size.value);
- }
- move({
- pace,
- emitChange: true
- });
- } else if (delta.value) {
- move({
- pace: 0
- });
- }
- state.swiping = false;
- autoplay();
- };
- const swipeTo = (index, options = {}) => {
- correctPosition();
- touch.reset();
- (0, import_use.doubleRaf)(() => {
- let targetIndex;
- if (props.loop && index === count.value) {
- targetIndex = state.active === 0 ? 0 : index;
- } else {
- targetIndex = index % count.value;
- }
- if (options.immediate) {
- (0, import_use.doubleRaf)(() => {
- state.swiping = false;
- });
- } else {
- state.swiping = false;
- }
- move({
- pace: targetIndex - state.active,
- emitChange: true
- });
- });
- };
- const renderDot = (_, index) => {
- const active = index === activeIndicator.value;
- const style = active ? {
- backgroundColor: props.indicatorColor
- } : void 0;
- return (0, import_vue.createVNode)("i", {
- "style": style,
- "class": bem("indicator", {
- active
- })
- }, null);
- };
- const renderIndicator = () => {
- if (slots.indicator) {
- return slots.indicator({
- active: activeIndicator.value,
- total: count.value
- });
- }
- if (props.showIndicators && count.value > 1) {
- return (0, import_vue.createVNode)("div", {
- "class": bem("indicators", {
- vertical: props.vertical
- })
- }, [Array(count.value).fill("").map(renderDot)]);
- }
- };
- (0, import_use_expose.useExpose)({
- prev,
- next,
- state,
- resize,
- swipeTo
- });
- linkChildren({
- size,
- props,
- count,
- activeIndicator
- });
- (0, import_vue2.watch)(() => props.initialSwipe, (value) => initialize(+value));
- (0, import_vue2.watch)(count, () => initialize(state.active));
- (0, import_vue2.watch)(() => props.autoplay, autoplay);
- (0, import_vue2.watch)([import_utils.windowWidth, import_utils.windowHeight], resize);
- (0, import_vue2.watch)((0, import_use.usePageVisibility)(), (visible) => {
- if (visible === "visible") {
- autoplay();
- } else {
- stopAutoplay();
- }
- });
- (0, import_vue2.onMounted)(initialize);
- (0, import_vue2.onActivated)(() => initialize(state.active));
- (0, import_on_popup_reopen.onPopupReopen)(() => initialize(state.active));
- (0, import_vue2.onDeactivated)(stopAutoplay);
- (0, import_vue2.onBeforeUnmount)(stopAutoplay);
- (0, import_use.useEventListener)("touchmove", onTouchMove, {
- target: track
- });
- return () => {
- var _a;
- return (0, import_vue.createVNode)("div", {
- "ref": root,
- "class": bem()
- }, [(0, import_vue.createVNode)("div", {
- "ref": track,
- "style": trackStyle.value,
- "class": bem("track", {
- vertical: props.vertical
- }),
- "onTouchstartPassive": onTouchStart,
- "onTouchend": onTouchEnd,
- "onTouchcancel": onTouchEnd
- }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]), renderIndicator()]);
- };
- }
- });
|