UNPKG

@gyenno/nutui-taro

Version:

京东风格的轻量级移动端 Vue2、Vue3 组件库(支持小程序开发)

318 lines (317 loc) 9.39 kB
import { reactive, computed, watch, onMounted, toRefs, resolveComponent, openBlock, createBlock, withCtx, createElementVNode, createElementBlock, Fragment, renderList, createCommentVNode, createTextVNode, toDisplayString, normalizeStyle, createVNode } from "vue"; import { c as createComponent } from "./component-25dcca32.js"; import { f as funInterceptor } from "./Interceptor-157a0193.js"; import { P as Popup } from "./index.taro-72b18dbf.js"; import Swiper from "./Swiper.js"; import SwiperItem from "./SwiperItem.js"; import Taro from "@tarojs/taro"; import { CircleClose } from "@nutui/icons-vue-taro"; import { _ as _export_sfc } from "./_plugin-vue_export-helper-cc2b3d55.js"; import "../locale/lang"; import "./Overlay.js"; import "./index-7a7385e4.js"; import "./index-7fb26863.js"; import "./index-79c5dc33.js"; import "./raf-df951186.js"; const { create } = createComponent("image-preview"); const _sfc_main = create({ props: { show: { type: Boolean, default: false }, images: { type: Array, default: () => [] }, contentClose: { type: Boolean, default: false }, initNo: { type: Number, default: 0 }, paginationVisible: { type: Boolean, default: false }, paginationColor: { type: String, default: "#fff" }, autoplay: { type: [Number, String], default: 3e3 }, showIndex: { type: Boolean, default: true }, closeable: { type: Boolean, default: false }, closeIconPosition: { type: String, default: "top-right" // top-right top-left }, beforeClose: Function, isLoop: { type: Boolean, default: true } }, emits: ["close", "change"], components: { [Popup.name]: Popup, [Swiper.name]: Swiper, [SwiperItem.name]: SwiperItem, CircleClose }, setup(props, { emit }) { const state = reactive({ showPop: false, active: 0, options: { muted: true, controls: true }, eleImg: null, store: { scale: 1, moveable: false, originScale: 1, oriDistance: 1 }, lastTouchEndTime: 0, // 用来辅助监听双击 ENV: Taro.getEnv(), ENV_TYPE: Taro.ENV_TYPE }); const styles = computed(() => { let style = {}; if (props.closeIconPosition == "top-right") { style.right = "10px"; } else { style.left = "10px"; } return style; }); const setActive = (active) => { if (active !== state.active) { state.active = active; emit("change", state.active); } }; const closeOnImg = () => { if (props.contentClose) { onClose(); } }; const onClose = () => { funInterceptor(props.beforeClose, { args: [state.active], done: () => closeDone() }); }; const closeDone = () => { state.showPop = false; state.store.scale = 1; scaleNow(); emit("close"); }; const getDistance = (first, second) => { return Math.hypot(Math.abs(second.x - first.x), Math.abs(second.y - first.y)); }; const scaleNow = () => { if (state.eleImg != null) { state.eleImg.style.transform = "scale(" + state.store.scale + ")"; } }; const onTouchStart = (event) => { const curTouchTime = (/* @__PURE__ */ new Date()).getTime(); if (curTouchTime - state.lastTouchEndTime < 300) { const store2 = state.store; if (store2.scale > 1) { store2.scale = 1; } else if (store2.scale == 1) { store2.scale = 2; } scaleNow(); } var touches = event.touches; var events = touches[0]; var events2 = touches[1]; const store = state.store; store.moveable = true; if (events2) { store.oriDistance = getDistance( { x: events.pageX, y: events.pageY }, { x: events2.pageX, y: events2.pageY } ); } store.originScale = store.scale || 1; }; const onTouchMove = (event) => { if (!state.store.moveable) { return; } const store = state.store; var touches = event.touches; var events = touches[0]; var events2 = touches[1]; if (events2) { const curDistance = getDistance( { x: events.pageX, y: events.pageY }, { x: events2.pageX, y: events2.pageY } ); const curScale = curDistance / store.oriDistance; store.scale = store.originScale * curScale; if (store.scale > 3) { store.scale = 3; } scaleNow(); } }; const onTouchEnd = () => { state.lastTouchEndTime = (/* @__PURE__ */ new Date()).getTime(); const store = state.store; store.moveable = false; if (store.scale < 1.1 && store.scale > 1 || store.scale < 1) { store.scale = 1; scaleNow(); } }; const init = () => { state.eleImg = document.querySelector(".nut-image-preview"); document.addEventListener("touchmove", onTouchMove); document.addEventListener("touchend", onTouchEnd); document.addEventListener("touchcancel", onTouchEnd); }; watch( () => props.show, (val) => { state.showPop = val; if (val) { setActive(props.initNo); init(); } } ); watch( () => props.initNo, (val) => { if (val != state.active) setActive(val); } ); onMounted(() => { setActive(props.initNo); }); return { ...toRefs(state), setActive, onClose, closeOnImg, onTouchStart, onTouchMove, onTouchEnd, getDistance, scaleNow, styles }; } }); const _hoisted_1 = ["src"]; const _hoisted_2 = ["src"]; const _hoisted_3 = { key: 0, class: "nut-image-preview-index" }; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_nut_swiper_item = resolveComponent("nut-swiper-item"); const _component_nut_swiper = resolveComponent("nut-swiper"); const _component_CircleClose = resolveComponent("CircleClose"); const _component_nut_popup = resolveComponent("nut-popup"); return openBlock(), createBlock(_component_nut_popup, { "pop-class": "nut-image-preview-custom-pop", visible: _ctx.showPop, "onUpdate:visible": _cache[2] || (_cache[2] = ($event) => _ctx.showPop = $event), onClosed: _ctx.onClose }, { default: withCtx(() => [ createElementVNode("view", { class: "nut-image-preview", onTouchstartCapture: _cache[0] || (_cache[0] = (...args) => _ctx.onTouchStart && _ctx.onTouchStart(...args)) }, [ _ctx.showPop ? (openBlock(), createBlock(_component_nut_swiper, { key: 0, "auto-play": _ctx.autoplay, class: "nut-image-preview-swiper", loop: _ctx.isLoop, "is-preventDefault": false, direction: "horizontal", onChange: _ctx.setActive, "init-page": _ctx.initNo, "pagination-visible": _ctx.paginationVisible, "pagination-color": _ctx.paginationColor }, { default: withCtx(() => [ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.images, (item, index) => { return openBlock(), createBlock(_component_nut_swiper_item, { key: index, onClick: _ctx.onClose }, { default: withCtx(() => [ _ctx.ENV != _ctx.ENV_TYPE.WEB ? (openBlock(), createElementBlock("image", { key: 0, mode: "aspectFit", src: item.src, class: "nut-image-preview-taro-img" }, null, 8, _hoisted_1)) : (openBlock(), createElementBlock("img", { key: 1, src: item.src, mode: "aspectFit", class: "nut-image-preview-img" }, null, 8, _hoisted_2)) ]), _: 2 }, 1032, ["onClick"]); }), 128)) ]), _: 1 }, 8, ["auto-play", "loop", "onChange", "init-page", "pagination-visible", "pagination-color"])) : createCommentVNode("", true) ], 32), createTextVNode(), _ctx.showIndex ? (openBlock(), createElementBlock("view", _hoisted_3, toDisplayString(_ctx.active + 1) + " / " + toDisplayString(_ctx.images.length), 1)) : createCommentVNode("", true), createTextVNode(), _ctx.closeable ? (openBlock(), createElementBlock("view", { key: 1, class: "nut-image-preview-close-icon", onClick: _cache[1] || (_cache[1] = (...args) => _ctx.onClose && _ctx.onClose(...args)), style: normalizeStyle(_ctx.styles) }, [ createVNode(_component_CircleClose, { color: "#ffffff" }) ], 4)) : createCommentVNode("", true) ]), _: 1 }, 8, ["visible", "onClosed"]); } const index_taro = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]); export { index_taro as default };