@gyenno/nutui-taro
Version:
京东风格的轻量级移动端 Vue2、Vue3 组件库(支持小程序开发)
318 lines (317 loc) • 9.39 kB
JavaScript
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
};