|
@@ -0,0 +1,100 @@
|
|
|
|
+<template>
|
|
|
|
+ <teleport to="body">
|
|
|
|
+ <div class="dialog-container" :style="positionStyle">
|
|
|
|
+ <header
|
|
|
|
+ ref="mouseHandler"
|
|
|
|
+ class="tw-flex tw-place-content-between"
|
|
|
|
+ @mousedown="handleMouseDown"
|
|
|
|
+ >
|
|
|
|
+ <div class="tw-text-2xl tw-cursor-move">{{ title }}</div>
|
|
|
|
+ <a-button shape="circle" @click="close">
|
|
|
|
+ <template #icon><CloseOutlined /></template>
|
|
|
|
+ </a-button>
|
|
|
|
+ </header>
|
|
|
|
+
|
|
|
|
+ <div class="tw-m-1">
|
|
|
|
+ <slot></slot>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </teleport>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script lang="ts">
|
|
|
|
+import { store } from "@/features/mark/store";
|
|
|
|
+import { defineComponent, reactive, ref } from "vue";
|
|
|
|
+import { CloseOutlined } from "@ant-design/icons-vue";
|
|
|
|
+
|
|
|
|
+export default defineComponent({
|
|
|
|
+ components: { CloseOutlined },
|
|
|
|
+ props: {
|
|
|
|
+ title: { type: String, default: "" },
|
|
|
|
+ top: { type: String, default: "10%" },
|
|
|
|
+ },
|
|
|
|
+ setup({ top }) {
|
|
|
|
+ const close = () => {
|
|
|
|
+ store.setting.uiSetting["answer.paper.modal"] = false;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ const positionStyle = reactive({
|
|
|
|
+ top: top,
|
|
|
|
+ left: "10%",
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ const mouseHandler = ref((null as unknown) as HTMLHeadElement);
|
|
|
|
+
|
|
|
|
+ const mousePosition = {
|
|
|
|
+ offsetX: 0,
|
|
|
|
+ offsetY: 0,
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ const handleMouseDown = (e: MouseEvent) => {
|
|
|
|
+ mouseHandler.value.addEventListener("mousemove", handleMouseMove);
|
|
|
|
+ mouseHandler.value.addEventListener("mouseup", handleMouseUp);
|
|
|
|
+ // console.log(e);
|
|
|
|
+ const { offsetX, offsetY } = e;
|
|
|
|
+ mousePosition.offsetX = offsetX;
|
|
|
|
+ mousePosition.offsetY = offsetY;
|
|
|
|
+ };
|
|
|
|
+ const handleMouseMove = (e: MouseEvent) => {
|
|
|
|
+ const { pageX, pageY, clientX, clientY } = e;
|
|
|
|
+ const windowWidth = window.innerWidth;
|
|
|
|
+ const windowHeight = window.innerHeight;
|
|
|
|
+ const newXRatio = (clientX - mousePosition.offsetX) / windowWidth;
|
|
|
|
+ const newYRatio = (clientY - mousePosition.offsetY) / windowHeight;
|
|
|
|
+ // console.log({
|
|
|
|
+ // offsetX: mousePosition.offsetX,
|
|
|
|
+ // pageX,
|
|
|
|
+ // offsetY: mousePosition.offsetY,
|
|
|
|
+ // pageY,
|
|
|
|
+ // newYRatio,
|
|
|
|
+ // newXRatio,
|
|
|
|
+ // });
|
|
|
|
+ positionStyle.top = newYRatio * 100 + "%";
|
|
|
|
+ positionStyle.left = newXRatio * 100 + "%";
|
|
|
|
+ };
|
|
|
|
+ const handleMouseUp = (e: MouseEvent) => {
|
|
|
|
+ mouseHandler.value.removeEventListener("mousemove", handleMouseMove);
|
|
|
|
+ mouseHandler.value.removeEventListener("mouseup", handleMouseUp);
|
|
|
|
+ };
|
|
|
|
+ return {
|
|
|
|
+ close,
|
|
|
|
+ positionStyle,
|
|
|
|
+ mouseHandler,
|
|
|
|
+ handleMouseDown,
|
|
|
|
+ handleMouseMove,
|
|
|
|
+ handleMouseUp,
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+});
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style scoped>
|
|
|
|
+.dialog-container {
|
|
|
|
+ z-index: 9000;
|
|
|
|
+ position: absolute;
|
|
|
|
+ min-width: 100px;
|
|
|
|
+ background-color: white;
|
|
|
|
+ border: 1px solid grey;
|
|
|
|
+ border-radius: 5px;
|
|
|
|
+}
|
|
|
|
+</style>
|