mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-09-29 13:40:02 +08:00
117 lines
2.5 KiB
TypeScript
117 lines
2.5 KiB
TypeScript
import { computed, ComputedRef, onBeforeUnmount, ref, watch } from 'vue';
|
|
|
|
import { useServices } from './use-services';
|
|
|
|
interface State {
|
|
status: boolean;
|
|
top: number;
|
|
left: number;
|
|
}
|
|
|
|
export const useFloatBox = (slideKeys: ComputedRef<string[]>) => {
|
|
const { uiService } = useServices();
|
|
|
|
const floatBoxStates = ref<{
|
|
[key in (typeof slideKeys.value)[number]]: State;
|
|
}>(
|
|
slideKeys.value.reduce(
|
|
(total, cur) => ({
|
|
...total,
|
|
[cur]: {
|
|
status: false,
|
|
top: 0,
|
|
left: 0,
|
|
},
|
|
}),
|
|
{},
|
|
),
|
|
);
|
|
|
|
const showingBoxKeys = computed(() =>
|
|
Object.keys(floatBoxStates.value).filter((key) => floatBoxStates.value[key].status),
|
|
);
|
|
|
|
const dragState = {
|
|
startOffset: {
|
|
x: 0,
|
|
y: 0,
|
|
},
|
|
isDragging: false,
|
|
};
|
|
|
|
const dragstartHandler = (e: DragEvent) => {
|
|
dragState.isDragging = true;
|
|
|
|
dragState.startOffset.x = e.clientX;
|
|
dragState.startOffset.y = e.clientY;
|
|
};
|
|
|
|
const effectiveDistance = 20;
|
|
|
|
const dragendHandler = (key: string, e: DragEvent) => {
|
|
if (!dragState.isDragging) return;
|
|
|
|
const { startOffset } = dragState;
|
|
|
|
if (
|
|
Math.abs(startOffset.x - e.clientX) > effectiveDistance ||
|
|
Math.abs(startOffset.y - e.clientY) > effectiveDistance
|
|
) {
|
|
const navMenuRect = uiService.get('navMenuRect');
|
|
floatBoxStates.value[key] = {
|
|
left: e.clientX,
|
|
top: navMenuRect.top + navMenuRect.height,
|
|
status: true,
|
|
};
|
|
}
|
|
|
|
dragState.isDragging = false;
|
|
};
|
|
|
|
const dragoverHandler = (e: DragEvent) => {
|
|
if (!dragState.isDragging) return;
|
|
e.preventDefault();
|
|
};
|
|
|
|
const blurHandler = () => {
|
|
dragState.startOffset.x = 0;
|
|
dragState.startOffset.y = 0;
|
|
|
|
dragState.isDragging = false;
|
|
};
|
|
|
|
globalThis.document.body.addEventListener('dragover', dragoverHandler);
|
|
globalThis.addEventListener('blur', blurHandler);
|
|
|
|
onBeforeUnmount(() => {
|
|
globalThis.document.body.removeEventListener('dragover', dragoverHandler);
|
|
globalThis.removeEventListener('blur', blurHandler);
|
|
});
|
|
|
|
watch(
|
|
() => slideKeys.value,
|
|
(slideKeys) => {
|
|
slideKeys.forEach((key) => {
|
|
if (!floatBoxStates.value[key]) {
|
|
floatBoxStates.value[key] = {
|
|
status: false,
|
|
top: 0,
|
|
left: 0,
|
|
};
|
|
}
|
|
});
|
|
},
|
|
{
|
|
deep: true,
|
|
immediate: true,
|
|
},
|
|
);
|
|
|
|
return {
|
|
dragstartHandler,
|
|
dragendHandler,
|
|
floatBoxStates,
|
|
showingBoxKeys,
|
|
};
|
|
};
|