|
@@ -0,0 +1,153 @@
|
|
|
+// 弹窗拖动
|
|
|
+import { ref, Ref, watch, nextTick, computed } from 'vue';
|
|
|
+
|
|
|
+type posType = {
|
|
|
+ top: number;
|
|
|
+ left: number;
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * @params classList 可拖动地方的class值,也为唯一值
|
|
|
+ * @params boxClass 容器class值必须为唯一值,这个class和useid拼接 作为缓存主键
|
|
|
+ * @params dragShow 弹窗是否显示
|
|
|
+ * @params userId 当前用户id
|
|
|
+ */
|
|
|
+export default function useDrag(
|
|
|
+ classList: string[],
|
|
|
+ boxClass: string,
|
|
|
+ dragShow: Ref<boolean>,
|
|
|
+ userId: string
|
|
|
+) {
|
|
|
+ const pos = ref<posType>({
|
|
|
+ top: -1, // -1 为初始值 代表没有缓存 默认居中
|
|
|
+ left: -1
|
|
|
+ });
|
|
|
+ const useIdDargClass = userId + boxClass;
|
|
|
+ watch(dragShow, () => {
|
|
|
+ if (dragShow.value) {
|
|
|
+ // 初始化pos值
|
|
|
+ initPos();
|
|
|
+ window.addEventListener('resize', refreshPos);
|
|
|
+ nextTick(() => {
|
|
|
+ const boxClassDom = document.querySelector(
|
|
|
+ `.${boxClass}`
|
|
|
+ ) as HTMLElement;
|
|
|
+ if (!boxClassDom) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ classList.map((className: string) => {
|
|
|
+ const classDom = document.querySelector(
|
|
|
+ `.${className}`
|
|
|
+ ) as HTMLElement;
|
|
|
+ if (classDom) {
|
|
|
+ classDom.style.cursor = 'move';
|
|
|
+ drag(classDom, boxClassDom, pos);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ window.removeEventListener('resize', refreshPos);
|
|
|
+ setCachePos(useIdDargClass, pos.value);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ const styleDrag = computed(() => {
|
|
|
+ // 没有设置拖动的时候保持原本的
|
|
|
+ return pos.value.left === -1 && pos.value.top === -1
|
|
|
+ ? {}
|
|
|
+ : {
|
|
|
+ position: 'fixed',
|
|
|
+ left: `${pos.value.left}px`,
|
|
|
+ top: `${pos.value.top}px`
|
|
|
+ };
|
|
|
+ });
|
|
|
+ function initPos() {
|
|
|
+ const posCache = getCachePos(useIdDargClass);
|
|
|
+ // 有缓存 用缓存的值,没有缓存用默认
|
|
|
+ if (posCache) {
|
|
|
+ pos.value = posCache;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ function refreshPos() {
|
|
|
+ const boxClassDom = document.querySelector(`.${boxClass}`) as HTMLElement;
|
|
|
+ if (!boxClassDom) return;
|
|
|
+ const parentElementRect = boxClassDom.getBoundingClientRect();
|
|
|
+ const clientWidth = document.documentElement.clientWidth;
|
|
|
+ const clientHeight = document.documentElement.clientHeight;
|
|
|
+ const { top, left } = pos.value;
|
|
|
+ const maxLeft = clientWidth - parentElementRect.width;
|
|
|
+ const maxTop = clientHeight - parentElementRect.height;
|
|
|
+ let moveX = left;
|
|
|
+ let moveY = top;
|
|
|
+ const minLeft = 0;
|
|
|
+ const minTop = 0;
|
|
|
+ moveX = moveX < minLeft ? minLeft : moveX > maxLeft ? maxLeft : moveX;
|
|
|
+ moveY = moveY < minTop ? minTop : moveY > maxTop ? maxTop : moveY;
|
|
|
+ pos.value = {
|
|
|
+ top: moveY,
|
|
|
+ left: moveX
|
|
|
+ };
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ pos,
|
|
|
+ styleDrag
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+// 拖动
|
|
|
+function drag(el: HTMLElement, parentElement: HTMLElement, pos: Ref<posType>) {
|
|
|
+ function mousedown(e: MouseEvent) {
|
|
|
+ const parentElementRect = parentElement.getBoundingClientRect();
|
|
|
+ const downX = e.clientX;
|
|
|
+ const downY = e.clientY;
|
|
|
+ const clientWidth = document.documentElement.clientWidth;
|
|
|
+ const clientHeight = document.documentElement.clientHeight;
|
|
|
+ const maxLeft = clientWidth - parentElementRect.width;
|
|
|
+ const maxTop = clientHeight - parentElementRect.height;
|
|
|
+ const minLeft = 0;
|
|
|
+ const minTop = 0;
|
|
|
+ function onMousemove(e: MouseEvent) {
|
|
|
+ let moveX = parentElementRect.left + (e.clientX - downX);
|
|
|
+ let moveY = parentElementRect.top + (e.clientY - downY);
|
|
|
+ moveX = moveX < minLeft ? minLeft : moveX > maxLeft ? maxLeft : moveX;
|
|
|
+ moveY = moveY < minTop ? minTop : moveY > maxTop ? maxTop : moveY;
|
|
|
+ pos.value = {
|
|
|
+ top: moveY,
|
|
|
+ left: moveX
|
|
|
+ };
|
|
|
+ }
|
|
|
+ function onMouseup() {
|
|
|
+ document.removeEventListener('mousemove', onMousemove);
|
|
|
+ document.removeEventListener('mouseup', onMouseup);
|
|
|
+ }
|
|
|
+ document.addEventListener('mousemove', onMousemove);
|
|
|
+ document.addEventListener('mouseup', onMouseup);
|
|
|
+ }
|
|
|
+ el.addEventListener('mousedown', mousedown);
|
|
|
+}
|
|
|
+
|
|
|
+// 缓存
|
|
|
+const localStorageName = 'dragCachePos';
|
|
|
+function getCachePos(useIdDargClass: string): null | undefined | posType {
|
|
|
+ const localCachePos = localStorage.getItem(localStorageName);
|
|
|
+ if (localCachePos) {
|
|
|
+ try {
|
|
|
+ return JSON.parse(localCachePos)[useIdDargClass];
|
|
|
+ } catch {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+}
|
|
|
+function setCachePos(useIdDargClass: string, pos: posType) {
|
|
|
+ const localCachePos = localStorage.getItem(localStorageName);
|
|
|
+ let cachePosObj: Record<string, any> = {};
|
|
|
+ if (localCachePos) {
|
|
|
+ try {
|
|
|
+ cachePosObj = JSON.parse(localCachePos);
|
|
|
+ } catch {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ }
|
|
|
+ cachePosObj[useIdDargClass] = pos;
|
|
|
+ localStorage.setItem(localStorageName, JSON.stringify(cachePosObj));
|
|
|
+}
|