UNPKG

tdesign-mobile-vue

Version:
524 lines (516 loc) 21.3 kB
/** * tdesign v1.9.3 * (c) 2025 TDesign Group * @license MIT */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _slicedToArray = require('@babel/runtime/helpers/slicedToArray'); var vue = require('vue'); var tdesignIconsVueNext = require('tdesign-icons-vue-next'); var config = require('../config.js'); var imageViewer_props = require('./props.js'); var hooks_useDefaultValue = require('../hooks/useDefaultValue.js'); var hooks_useGesture = require('../hooks/useGesture.js'); var hooks_useVModel = require('../hooks/useVModel.js'); var hooks_tnode = require('../hooks/tnode.js'); var hooks_useClass = require('../hooks/useClass.js'); var swiper_index = require('../swiper/index.js'); var shared_util = require('../shared/util.js'); require('../_chunks/dep-6df33aaf.js'); require('../_chunks/dep-3d4c38f1.js'); require('../_chunks/dep-afa9f3f2.js'); require('../_chunks/dep-2f809ed9.js'); require('@babel/runtime/helpers/typeof'); require('../_chunks/dep-ae809b86.js'); require('../_chunks/dep-757b152c.js'); require('../_chunks/dep-2b08c0a6.js'); require('../_chunks/dep-5be9198d.js'); require('@use-gesture/vanilla'); require('../hooks/render-tnode.js'); require('../_chunks/dep-ef223206.js'); require('../_chunks/dep-c3cb976c.js'); require('../_chunks/dep-a7319409.js'); require('../_chunks/dep-288156c7.js'); require('../_chunks/dep-88fe047a.js'); require('../_chunks/dep-675798b4.js'); require('../_chunks/dep-ccc9ad3d.js'); require('../_chunks/dep-d950aa21.js'); require('../_chunks/dep-a697b1b9.js'); require('../_chunks/dep-4dfb9b9c.js'); require('../_chunks/dep-7c911ba3.js'); require('../_common/js/utils/general.js'); require('../_chunks/dep-21f18d3b.js'); require('@babel/runtime/helpers/defineProperty'); require('../_chunks/dep-b9642a56.js'); require('../_common/js/global-config/mobile/default-config.js'); require('../_common/js/global-config/mobile/locale/zh_CN.js'); require('../_chunks/dep-28b1e09d.js'); require('../_chunks/dep-57aa1aa0.js'); require('dayjs'); require('../_chunks/dep-85204fa0.js'); require('../_chunks/dep-f6b14f80.js'); require('../_chunks/dep-a8d60643.js'); require('../_chunks/dep-49f0a63e.js'); require('../_chunks/dep-c65deed7.js'); require('../_chunks/dep-94eeec5a.js'); require('../_chunks/dep-060bf1cf.js'); require('../_chunks/dep-0e05e959.js'); require('../_chunks/dep-324da301.js'); require('../_chunks/dep-da6dc2cf.js'); require('../swiper/swiper.js'); require('../swipe-cell/useSwipe.js'); require('@vueuse/core'); require('../shared/dom.js'); require('../swiper/props.js'); require('../_chunks/dep-ff4786c0.js'); require('../swiper/swiper-item.js'); require('../shared/component.js'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray); function _isSlot(s) { return typeof s === 'function' || Object.prototype.toString.call(s) === '[object Object]' && !vue.isVNode(s); } var prefix = config["default"].prefix; var TAP_TIME = 300; var _ImageViewer = vue.defineComponent({ name: "".concat(prefix, "-image-viewer"), props: imageViewer_props["default"], emits: ["close", "index-change", "update:visible", "update:modelValue", "update:index", "delete"], setup: function setup(props2, _ref) { var _props2$defaultIndex; var emit = _ref.emit; var imageViewerClass = hooks_useClass.usePrefixClass("image-viewer"); var state = vue.reactive({ dblTapZooming: false, zooming: false, scale: 1, touchIndex: 0, dragging: false, draggedX: 0, draggedY: 0, extraDraggedX: 0 }); var _toRefs = vue.toRefs(props2), index = _toRefs.index, visible = _toRefs.visible, modelValue = _toRefs.modelValue; var _useVModel = hooks_useVModel["default"](visible, modelValue, props2.defaultVisible, function () {}, "visible"), _useVModel2 = _slicedToArray__default["default"](_useVModel, 2), visibleValue = _useVModel2[0], setVisibleValue = _useVModel2[1]; var _useDefaultValue = hooks_useDefaultValue["default"](index, (_props2$defaultIndex = props2.defaultIndex) !== null && _props2$defaultIndex !== void 0 ? _props2$defaultIndex : 0, props2.onIndexChange, "index"), _useDefaultValue2 = _slicedToArray__default["default"](_useDefaultValue, 2), currentIndex = _useDefaultValue2[0], setCurrentIndex = _useDefaultValue2[1]; var preloadImageIndex = vue.computed(function () { var lastIndex = props2.images.length - 1; if ([void 0, 0].includes(currentIndex.value)) { return [0, 1, lastIndex]; } if (currentIndex.value === lastIndex) { return [lastIndex, lastIndex - 1, 0]; } var prev = currentIndex.value - 1 >= 0 ? currentIndex.value - 1 : lastIndex; var next = currentIndex.value + 1 <= lastIndex ? currentIndex.value + 1 : 0; return [currentIndex.value, prev, next]; }); var imageInfoList = vue.computed(function () { return props2.images.map(function (image, index2) { var imageInfo; if (typeof image === "string") { imageInfo = { url: image, align: "center" }; } else { imageInfo = image; } return { image: imageInfo, preload: preloadImageIndex.value.includes(index2) }; }); }); var disabled = vue.ref(false); var rootRef = vue.ref(); var imagesSize = vue.reactive({}); var swiperRootRef = vue.ref(); var swiperItemRefs = vue.ref([]); var gestureRef = vue.ref(); var renderTNodeJSX = hooks_tnode.useTNodeJSX(); var closeNode = vue.computed(function () { return renderTNodeJSX("closeBtn", vue.h(tdesignIconsVueNext.CloseIcon)); }); var deleteNode = vue.computed(function () { return renderTNodeJSX("deleteBtn", vue.h(tdesignIconsVueNext.DeleteIcon)); }); var imageTransform = vue.computed(function () { var scale = state.scale, draggedX = state.draggedX, draggedY = state.draggedY; return "matrix(".concat(scale, ", 0, 0, ").concat(scale, ", ").concat(draggedX, ", ").concat(draggedY, ")"); }); var imageTransitionDuration = vue.computed(function () { var zooming = state.zooming, dragging = state.dragging; return zooming || dragging ? "transition-duration: 0s" : "transition-duration: 0.3s"; }); var beforeClose = function beforeClose() { state.dblTapZooming = false; state.zooming = false; state.scale = 1; state.dragging = false; state.draggedX = 0; state.draggedY = 0; state.extraDraggedX = 0; }; var handleClose = function handleClose(e, trigger) { beforeClose(); setVisibleValue(false); emit("close", { trigger: trigger, e: e }); }; var handleDelete = function handleDelete() { var _currentIndex$value; emit("delete", (_currentIndex$value = currentIndex.value) !== null && _currentIndex$value !== void 0 ? _currentIndex$value : 0); }; var setImagePreload = function setImagePreload(index2) { var nextIndex = index2 >= imageInfoList.value.length - 1 ? 0 : index2 + 1; var preIndex = index2 <= 0 ? imageInfoList.value.length - 1 : index2 - 1; imageInfoList.value[preIndex].preload = true; imageInfoList.value[nextIndex].preload = true; }; var onSwiperChange = function onSwiperChange(index2, context) { if (currentIndex.value !== index2) { var trigger = currentIndex.value < index2 ? "next" : "prev"; setCurrentIndex(index2, { trigger: trigger }); setScale(1); setImagePreload(index2); } }; var onImgLoad = function onImgLoad(e, index2) { var height = e.target.height; imagesSize[index2] = { height: height }; }; var getMaxDraggedX = function getMaxDraggedX() { var _rootRef$value; var rootOffsetWidth = ((_rootRef$value = rootRef.value) === null || _rootRef$value === void 0 ? void 0 : _rootRef$value.offsetWidth) || 0; var scaledWidth = state.scale * rootOffsetWidth; return Math.max(0, (scaledWidth - rootOffsetWidth) / 2); }; var getMaxDraggedY = function getMaxDraggedY(index2) { var _rootRef$value2, _imagesSize$index, _imageInfoList$value$; var rootOffsetHeight = ((_rootRef$value2 = rootRef.value) === null || _rootRef$value2 === void 0 ? void 0 : _rootRef$value2.offsetHeight) || 0; var currentImageHeight = (imagesSize === null || imagesSize === void 0 || (_imagesSize$index = imagesSize[index2]) === null || _imagesSize$index === void 0 ? void 0 : _imagesSize$index.height) || 0; var currentImageScaledHeight = state.scale * currentImageHeight; var halfScaleHeight = (currentImageScaledHeight - currentImageHeight) / 2; if (currentImageScaledHeight <= rootOffsetHeight) { return { top: 0, bottom: 0 }; } var diffHeight = currentImageScaledHeight - rootOffsetHeight; var centerDraggedY = diffHeight / 2; var alignmentDraggedY = { start: { top: -diffHeight + halfScaleHeight, bottom: halfScaleHeight }, center: { top: -centerDraggedY, bottom: centerDraggedY }, end: { top: -halfScaleHeight, bottom: diffHeight - halfScaleHeight } }; var alignment = ((_imageInfoList$value$ = imageInfoList.value[index2]) === null || _imageInfoList$value$ === void 0 || (_imageInfoList$value$ = _imageInfoList$value$.image) === null || _imageInfoList$value$ === void 0 ? void 0 : _imageInfoList$value$.align) || "center"; return alignmentDraggedY[alignment]; }; var setScale = function setScale(scale) { scale = Math.min(scale, +props2.maxZoom + 1); if (scale !== state.scale) { state.scale = scale; if (scale === 1) { state.draggedX = 0; state.draggedY = 0; } } }; var dragStartTime; var dblTapTimer; var toggleScale = function toggleScale() { var scale = state.scale > 1 ? 1 : 2; setScale(scale); }; var onTransitionEnd = function onTransitionEnd(index2) { if (index2 === state.touchIndex) { state.dblTapZooming = false; clearTimeout(dblTapTimer); dblTapTimer = null; } }; var onTransitionStart = function onTransitionStart(index2) { if (index2 === state.touchIndex) { state.dblTapZooming = true; clearTimeout(dblTapTimer); } }; var checkTap = function checkTap(e) { var event = e.event; var deltaTime = Date.now() - dragStartTime; if (deltaTime < TAP_TIME && shared_util.isBrowser) { if (dblTapTimer) { clearTimeout(dblTapTimer); dblTapTimer = window.setTimeout(function () { clearTimeout(dblTapTimer); state.dragging = false; toggleScale(); }, TAP_TIME); } else { dblTapTimer = window.setTimeout(function () { handleClose(event, "overlay"); dblTapTimer = null; }, TAP_TIME); } } }; var onPinchChange = function onPinchChange(scale, index2) { state.zooming = true; state.touchIndex = index2; setScale(scale); }; var onPinchEnd = function onPinchEnd() { state.zooming = false; if (state.scale < 1) { setScale(1); } if (state.scale > props2.maxZoom) { state.scale = +props2.maxZoom; } }; var handlePinch = function handlePinch(pinState, index2) { var last = pinState.last, _pinState$offset = _slicedToArray__default["default"](pinState.offset, 1), d = _pinState$offset[0]; if (!(imagesSize !== null && imagesSize !== void 0 && imagesSize[index2])) return; if (state.dblTapZooming) return; if (!last) { onPinchChange(d, index2); } else { onPinchEnd(); } }; var handleDrag = function handleDrag(dragState, index2) { state.touchIndex = index2; var _ref2 = swiperRootRef.value || {}, setOffset = _ref2.setOffset; if (!(imagesSize !== null && imagesSize !== void 0 && imagesSize[index2])) return; var first = dragState.first, movement = dragState.movement, _movement = dragState._movement, elapsedTime = dragState.elapsedTime, tap = dragState.tap, offset = dragState.offset, overflow = dragState.overflow, _delta = dragState._delta; if (first) { dragStartTime = Date.now(); } if (tap && elapsedTime > 0 && elapsedTime < 300) { checkTap(dragState); return; } if (state.dblTapZooming) { dragState === null || dragState === void 0 || dragState.cancel(); return; } state.dragging = true; state.draggedY = (offset === null || offset === void 0 ? void 0 : offset[1]) || 0; if (state.scale === 1) return; state.draggedX = (offset === null || offset === void 0 ? void 0 : offset[0]) || 0; if (movement[0] !== _movement[0] && overflow[0] !== 0) { state.extraDraggedX += _delta[0] / 5; setOffset === null || setOffset === void 0 || setOffset(state.extraDraggedX, "X"); } else if (state.extraDraggedX !== 0) { state.extraDraggedX = 0; setOffset === null || setOffset === void 0 || setOffset(state.extraDraggedX, "X"); } }; var handleDragEnd = function handleDragEnd(dragState) { var overflow = dragState.overflow, last = dragState.last; var _ref3 = swiperRootRef.value || {}, goPrev = _ref3.goPrev, goNext = _ref3.goNext, swiperContainer = _ref3.swiperContainer; state.dragging = false; if (state.extraDraggedX !== 0 && last) { if (Math.abs(state.extraDraggedX) > 50) { state.extraDraggedX = 0; overflow[0] < 0 ? goNext === null || goNext === void 0 ? void 0 : goNext("touch") : goPrev === null || goPrev === void 0 ? void 0 : goPrev("touch"); return; } state.extraDraggedX = 0; vue.nextTick(function () { var _swiperContainer$styl, _swiperContainer$styl2, _swiperContainer$styl3, _swiperContainer$styl4; swiperContainer === null || swiperContainer === void 0 || (_swiperContainer$styl = swiperContainer.style) === null || _swiperContainer$styl === void 0 || (_swiperContainer$styl2 = _swiperContainer$styl.setProperty) === null || _swiperContainer$styl2 === void 0 || _swiperContainer$styl2.call(_swiperContainer$styl, "transform", "translateX(0)"); swiperContainer === null || swiperContainer === void 0 || (_swiperContainer$styl3 = swiperContainer.style) === null || _swiperContainer$styl3 === void 0 || (_swiperContainer$styl4 = _swiperContainer$styl3.setProperty) === null || _swiperContainer$styl4 === void 0 || _swiperContainer$styl4.call(_swiperContainer$styl3, "transition", "transform 0.3s"); }); } }; var gestureOptions = vue.reactive({ destroyInvisible: true, visible: !!visibleValue.value }); gestureRef.value = hooks_useGesture["default"](gestureOptions); vue.watch(function () { return visibleValue.value; }, function (newVal) { return gestureOptions.visible = !!newVal; }); vue.watch(function () { return [visibleValue.value, swiperItemRefs.value]; }, function (_ref4) { var _ref5 = _slicedToArray__default["default"](_ref4, 2), newVisible = _ref5[0], newRefs = _ref5[1]; if (!newVisible) return; vue.nextTick(function () { var _newRefs$forEach; (_newRefs$forEach = newRefs.forEach) === null || _newRefs$forEach === void 0 || _newRefs$forEach.call(newRefs, function (item, index2) { var _gestureRef$value; var $el = item.$el; (_gestureRef$value = gestureRef.value) === null || _gestureRef$value === void 0 || _gestureRef$value.create($el, { onDrag: function onDrag(dragState) { return handleDrag(dragState, index2); }, onDragEnd: function onDragEnd(dragState) { return handleDragEnd(dragState); }, onPinch: function onPinch(pinchState) { return handlePinch(pinchState, index2); } }, { drag: { from: function from() { return [state.draggedX, state.draggedY]; }, pointer: { touch: true }, bounds: function bounds() { return { top: getMaxDraggedY(index2).top, right: getMaxDraggedX(), bottom: getMaxDraggedY(index2).bottom, left: -getMaxDraggedX() }; } }, pinch: { from: function from() { return [state.scale, 0]; }, pointer: { touch: true } } }); }); }); }); vue.watch(function () { return state.scale; }, function (newVal) { return disabled.value = newVal !== 1; }); vue.onUnmounted(function () { clearTimeout(dblTapTimer); }); return function () { var _currentIndex$value2, _props2$images, _props2$images2; var _slot; return vue.createVNode(vue.Transition, { "name": "fade" }, { default: function _default() { return [visibleValue.value && vue.createVNode("div", { "ref": rootRef, "class": "".concat(imageViewerClass.value) }, [vue.createVNode("div", { "class": "".concat(imageViewerClass.value, "__mask"), "onClick": function onClick(e) { return handleClose(e, "overlay"); } }, null), vue.createVNode(swiper_index.Swiper, { "ref": swiperRootRef, "autoplay": false, "class": "".concat(imageViewerClass.value, "__content"), "height": "100vh", "defaultCurrent": currentIndex.value, "disabled": disabled.value, "onChange": onSwiperChange }, _isSlot(_slot = imageInfoList.value.map(function (info, index2) { return vue.createVNode(swiper_index.SwiperItem, { "ref": function ref(item) { return swiperItemRefs.value[index2] = item; }, "key": index2, "class": "".concat(imageViewerClass.value, "__swiper-item"), "style": "touch-action: none; align-items:".concat(info.image.align, ";") }, { default: function _default() { return [info.preload ? vue.createVNode("img", { "src": info.image.url, "style": "\n transform: ".concat(index2 === state.touchIndex ? imageTransform.value : "matrix(1, 0, 0, 1, 0, 0)", ";\n ").concat(imageTransitionDuration.value, ";"), "class": "".concat(imageViewerClass.value, "__img"), "onLoad": function onLoad(event) { return onImgLoad(event, index2); }, "onTransitionstart": function onTransitionstart(event) { if (event.target === event.currentTarget) { onTransitionStart(index2); } }, "onTransitionend": function onTransitionend(event) { if (event.target === event.currentTarget) { onTransitionEnd(index2); } } }, null) : vue.createVNode("span", null, null)]; } }); })) ? _slot : { default: function _default() { return [_slot]; } }), vue.createVNode("div", { "class": "".concat(imageViewerClass.value, "__nav") }, [vue.createVNode("div", { "class": "".concat(imageViewerClass.value, "__nav-close"), "onClick": function onClick(e) { return handleClose(e, "close-btn"); } }, [closeNode.value]), props2.showIndex && vue.createVNode("div", { "class": "".concat(imageViewerClass.value, "__nav-index") }, ["".concat(Math.min(((_currentIndex$value2 = currentIndex.value) !== null && _currentIndex$value2 !== void 0 ? _currentIndex$value2 : 0) + 1, (_props2$images = props2.images) === null || _props2$images === void 0 ? void 0 : _props2$images.length), "/").concat((_props2$images2 = props2.images) === null || _props2$images2 === void 0 ? void 0 : _props2$images2.length)]), vue.createVNode("div", { "class": "".concat(imageViewerClass.value, "__nav-delete"), "onClick": handleDelete }, [deleteNode.value])])])]; } }); }; } }); exports["default"] = _ImageViewer; //# sourceMappingURL=image-viewer.js.map