123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- <template>
- <teleport to="body">
- <div
- class="dialog-container"
- :style="positionStyle"
- @click="increaseZIndex"
- >
- <header
- ref="mouseHandler"
- class="tw-flex tw-place-content-between tw-items-center"
- >
- <div
- class="
- tw-text-base
- tw-ml-5
- tw-my-2
- tw-cursor-move
- tw-flex-grow
- tw-font-bold
- "
- @mousedown="handleDragMouseDown"
- >
- {{ title }}
- </div>
- <a-button shape="circle" size="small" @click="$emit('close')">
- <template #icon><CloseOutlined /></template>
- </a-button>
- </header>
- <div class="tw-m-1 tw-overflow-auto" style="height: calc(100% - 50px)">
- <slot></slot>
- </div>
- <div
- ref="resizeHandler"
- class="resize-handler"
- @mousedown="handleResizeMouseDown"
- ></div>
- </div>
- </teleport>
- </template>
- <script setup lang="ts">
- import { onMounted, onUpdated, reactive } from "vue";
- import { CloseOutlined } from "@ant-design/icons-vue";
- import { store } from "@/store/store";
- const { top, width, height, title, zIndex } = withDefaults(
- defineProps<{
- title: string;
- top?: string;
- width?: string;
- height?: string;
- zIndex?: number;
- }>(),
- {
- title: "无标题",
- top: "10%",
- width: "30%",
- height: "30%",
- zIndex: 1020,
- }
- );
- defineEmits(["close"]);
- const positionStyle = reactive({
- top,
- left: "10%",
- width,
- height,
- zIndex,
- });
- const savedStyle = JSON.parse(
- sessionStorage.getItem("dialog-" + title) ?? "{}"
- );
- if (savedStyle?.top) positionStyle.top = savedStyle?.top;
- if (savedStyle?.left) positionStyle.left = savedStyle?.left;
- if (savedStyle?.width) positionStyle.width = savedStyle?.width;
- if (savedStyle?.height) positionStyle.height = savedStyle?.height;
- let mouseHandler = $ref(null as unknown as HTMLHeadElement);
- let resizeHandler = $ref(null as unknown as HTMLDivElement);
- const mousePosition = {
- offsetX: 0,
- offsetY: 0,
- };
- const handleDragMouseDown = (e: MouseEvent) => {
- document.addEventListener("mousemove", handleDragMouseMove);
- document.addEventListener("mouseup", handleDragMouseUp);
- // console.log(e);
- const { clientX, clientY } = e;
- mousePosition.offsetX = clientX;
- mousePosition.offsetY = clientY;
- };
- const handleDragMouseMove = (e: MouseEvent) => {
- const { clientX, clientY } = e;
- const windowWidth = window.innerWidth;
- const windowHeight = window.innerHeight;
- const newXRatio =
- parseFloat(positionStyle.left) / 100 +
- (clientX - mousePosition.offsetX) / windowWidth;
- const newYRatio =
- parseFloat(positionStyle.top) / 100 +
- (clientY - mousePosition.offsetY) / windowHeight;
- // console.log({
- // offsetX: mousePosition.offsetX,
- // offsetY: mousePosition.offsetY,
- // newYRatio,
- // newXRatio,
- // });
- if (newYRatio > 0 && newYRatio < 0.95) {
- positionStyle.top = newYRatio * 100 + "%";
- }
- if (newXRatio > 0 && newXRatio < 0.95) {
- positionStyle.left = newXRatio * 100 + "%";
- }
- mousePosition.offsetX = clientX;
- mousePosition.offsetY = clientY;
- };
- const handleDragMouseUp = (e: MouseEvent) => {
- mousePosition.offsetX = 0;
- mousePosition.offsetY = 0;
- mouseHandler.removeEventListener("mousedown", handleDragMouseDown);
- document.removeEventListener("mousemove", handleDragMouseMove);
- document.removeEventListener("mouseup", handleDragMouseUp);
- };
- const handleResizeMouseDown = (e: MouseEvent) => {
- document.addEventListener("mousemove", handleResizeMouseMove);
- document.addEventListener("mouseup", handleResizeMouseUp);
- const { clientX, clientY } = e;
- mousePosition.offsetX = clientX;
- mousePosition.offsetY = clientY;
- };
- const handleResizeMouseMove = (e: MouseEvent) => {
- // console.log(e);
- // console.log("mouse move");
- const { clientX, clientY } = e;
- // @ts-ignore
- const newXRatio = clientX - mousePosition.offsetX;
- const newYRatio = clientY - mousePosition.offsetY;
- positionStyle.width = parseFloat(positionStyle.width) + newXRatio + "px";
- positionStyle.height = parseFloat(positionStyle.height) + newYRatio + "px";
- mousePosition.offsetX = clientX;
- mousePosition.offsetY = clientY;
- };
- const handleResizeMouseUp = (e: MouseEvent) => {
- mousePosition.offsetX = 0;
- mousePosition.offsetY = 0;
- resizeHandler.removeEventListener("mousedown", handleResizeMouseDown);
- document.removeEventListener("mousemove", handleResizeMouseMove);
- document.removeEventListener("mouseup", handleResizeMouseUp);
- };
- onMounted(() => {
- increaseZIndex();
- });
- onUpdated(() => {
- if (title) {
- sessionStorage.setItem("dialog-" + title, JSON.stringify(positionStyle));
- }
- });
- const increaseZIndex = () => {
- positionStyle.zIndex = store.maxModalZIndex++;
- if (store.maxModalZIndex === 5000) {
- store.maxModalZIndex = 1020;
- }
- };
- </script>
- <style scoped>
- .dialog-container {
- z-index: 1020;
- position: absolute;
- min-width: 100px;
- background-color: var(--app-container-bg-color);
- border: 1px solid var(--app-main-bg-color);
- border-radius: 5px;
- box-shadow: 0px 4px 8px 0px rgba(25, 27, 55, 0.1);
- }
- header {
- color: var(--app-main-text-color);
- border-bottom: 1px solid var(--app-main-bg-color);
- }
- .resize-handler {
- position: absolute;
- bottom: -10px;
- right: -10px;
- width: 20px;
- height: 20px;
- cursor: nwse-resize;
- }
- </style>
|