winbox-ui-next
Version:
We Design Vue 2.0: A Vue.js 3 UI Library
282 lines (281 loc) • 7.9 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
import { defineComponent, toRefs, ref, reactive, computed, watch, h } from "vue";
import useMergeState from "../_hooks/use-merge-state.js";
import { getPrefixCls } from "../_utils/global-config.js";
import PreviewArrow from "./preview-arrow.js";
import PreviewToolbar from "./preview-toolbar.js";
import useImageLoadStatus from "./hooks/use-image-load-status.js";
import useImageDrag from "./hooks/use-image-drag.js";
import IconLoading from "../icon/icon-loading/index.js";
import IconClose from "../icon/icon-close/index.js";
import IconZoomOut from "../icon/icon-zoom-out/index.js";
import IconZoomIn from "../icon/icon-zoom-in/index.js";
import IconFullscreen from "../icon/icon-fullscreen/index.js";
import IconRotateLeft from "../icon/icon-rotate-left/index.js";
import IconRotateRight from "../icon/icon-rotate-right/index.js";
import IconOriginalSize from "../icon/icon-original-size/index.js";
import usePopupOverflowHidden from "../_hooks/use-popup-overflow-hidden.js";
import usePopupContainer from "../_hooks/use-popup-container.js";
import getScale, { maxScale, minScale } from "./utils/get-scale.js";
import { useI18n } from "../locale/index.js";
import usePopupManager from "../_hooks/use-popup-manager.js";
const ROTATE_STEP = 90;
var _sfc_main = defineComponent({
name: "ImagePreview",
components: {
PreviewArrow,
PreviewToolbar,
IconLoading,
IconClose
},
props: {
renderToBody: {
type: Boolean,
default: true
},
src: {
type: String
},
visible: {
type: Boolean,
default: void 0
},
defaultVisible: {
type: Boolean,
default: false
},
maskClosable: {
type: Boolean,
default: true
},
closable: {
type: Boolean,
default: true
},
actionsLayout: {
type: Array,
default: () => [
"zoomOut",
"zoomIn",
"fullScreen",
"rotateRight",
"rotateLeft"
]
},
popupContainer: {
type: [Object, String]
},
inGroup: {
type: Boolean,
default: false
},
groupArrowProps: {
type: Object,
default: () => ({})
}
},
emits: [
"close",
"update:visible"
],
setup(props, {
emit
}) {
const {
t
} = useI18n();
const {
src,
popupContainer,
visible,
defaultVisible,
maskClosable
} = toRefs(props);
const refWrapper = ref();
const refImage = ref();
const prefixCls = getPrefixCls("image-preview");
const [mergedVisible, setVisible] = useMergeState(defaultVisible.value, reactive({
value: visible
}));
const classNames = computed(() => [prefixCls, {
[`${prefixCls}-hide`]: !mergedVisible.value
}]);
const container = usePopupContainer(document.body, reactive({
popupContainer
}));
const isFixed = computed(() => container.value === document.body);
const {
zIndex
} = usePopupManager("dialog", {
visible: mergedVisible
});
const wrapperStyles = computed(() => {
const positionStyles = isFixed.value ? {
zIndex: zIndex.value,
position: "fixed"
} : {
zIndex: "inherit",
position: "absolute"
};
return __spreadValues({}, positionStyles);
});
const {
isLoading,
isLoaded,
setLoadStatus
} = useImageLoadStatus();
const rotate = ref(0);
const scale = ref(1);
const {
translate,
moving,
resetTranslate
} = useImageDrag(reactive({
wrapperEl: refWrapper,
imageEl: refImage,
visible: mergedVisible,
scale
}));
const scaleValueVisible = ref(false);
let hideScaleTimer = null;
const showScaleValue = () => {
!scaleValueVisible.value && (scaleValueVisible.value = true);
hideScaleTimer && clearTimeout(hideScaleTimer);
hideScaleTimer = setTimeout(() => {
scaleValueVisible.value = false;
}, 1e3);
};
usePopupOverflowHidden(reactive({
container,
hidden: mergedVisible
}));
function reset() {
rotate.value = 0;
scale.value = 1;
resetTranslate();
}
watch([src, mergedVisible], () => {
if (mergedVisible.value) {
reset();
setLoadStatus("loading");
}
});
function close() {
if (mergedVisible.value) {
emit("close");
emit("update:visible", false);
setVisible(false);
}
}
function onMaskClick(e) {
if (maskClosable.value && e.target === e.currentTarget) {
close();
}
}
function changeScale(newScale) {
if (scale.value !== newScale) {
scale.value = newScale;
showScaleValue();
}
}
return {
prefixCls,
classNames,
container,
wrapperStyles,
scale,
translate,
rotate,
moving,
mergedVisible,
isLoading,
isLoaded,
scaleValueVisible,
refWrapper,
refImage,
onMaskClick,
onCloseClick: close,
onImgLoad() {
setLoadStatus("loaded");
},
onImgError() {
setLoadStatus("error");
},
actions: computed(() => [
{
key: "fullScreen",
name: t("imagePreview.fullScreen"),
content: () => h(IconFullscreen),
onClick: () => {
const wrapperRect = refWrapper.value.getBoundingClientRect();
const imgRect = refImage.value.getBoundingClientRect();
const newHeightScale = wrapperRect.height / (imgRect.height / scale.value);
const newWidthScale = wrapperRect.width / (imgRect.width / scale.value);
const newScale = Math.max(newHeightScale, newWidthScale);
changeScale(newScale);
}
},
{
key: "rotateRight",
name: t("imagePreview.rotateRight"),
content: () => h(IconRotateRight),
onClick: () => {
rotate.value = rotate.value === 0 ? 360 - ROTATE_STEP : rotate.value - ROTATE_STEP;
}
},
{
key: "rotateLeft",
name: t("imagePreview.rotateLeft"),
content: () => h(IconRotateLeft),
onClick: () => {
rotate.value = (rotate.value + ROTATE_STEP) % 360;
}
},
{
key: "zoomIn",
name: t("imagePreview.zoomIn"),
content: () => h(IconZoomIn),
onClick: () => {
const newScale = getScale(scale.value, "zoomIn");
changeScale(newScale);
},
disabled: scale.value === maxScale
},
{
key: "zoomOut",
name: t("imagePreview.zoomOut"),
content: () => h(IconZoomOut),
onClick: () => {
const newScale = getScale(scale.value, "zoomOut");
changeScale(newScale);
},
disabled: scale.value === minScale
},
{
key: "originalSize",
name: t("imagePreview.originalSize"),
content: () => h(IconOriginalSize),
onClick: () => {
changeScale(1);
}
}
])
};
}
});
export { _sfc_main as default };