fix(editor): Add touch event handlers to new canvas

This commit is contained in:
Csaba Tuncsik 2024-10-22 14:23:29 +02:00
parent 679fa4a10a
commit e2f0d2a553
No known key found for this signature in database
2 changed files with 84 additions and 2 deletions

View file

@ -18,7 +18,17 @@ import { Background } from '@vue-flow/background';
import { MiniMap } from '@vue-flow/minimap'; import { MiniMap } from '@vue-flow/minimap';
import Node from './elements/nodes/CanvasNode.vue'; import Node from './elements/nodes/CanvasNode.vue';
import Edge from './elements/edges/CanvasEdge.vue'; import Edge from './elements/edges/CanvasEdge.vue';
import { computed, onMounted, onUnmounted, provide, ref, toRef, useCssModule, watch } from 'vue'; import {
computed,
onBeforeUnmount,
onMounted,
onUnmounted,
provide,
ref,
toRef,
useCssModule,
watch,
} from 'vue';
import type { EventBus } from 'n8n-design-system'; import type { EventBus } from 'n8n-design-system';
import { createEventBus } from 'n8n-design-system'; import { createEventBus } from 'n8n-design-system';
import { useContextMenu, type ContextMenuAction } from '@/composables/useContextMenu'; import { useContextMenu, type ContextMenuAction } from '@/composables/useContextMenu';
@ -33,6 +43,7 @@ import { onKeyDown, onKeyUp, useDebounceFn } from '@vueuse/core';
import CanvasArrowHeadMarker from './elements/edges/CanvasArrowHeadMarker.vue'; import CanvasArrowHeadMarker from './elements/edges/CanvasArrowHeadMarker.vue';
import { CanvasNodeRenderType } from '@/types'; import { CanvasNodeRenderType } from '@/types';
import CanvasBackgroundStripedPattern from './elements/CanvasBackgroundStripedPattern.vue'; import CanvasBackgroundStripedPattern from './elements/CanvasBackgroundStripedPattern.vue';
import { useTouchEventsInVueFlow } from '@/composables/useTouchEventsInVueFlow';
const $style = useCssModule(); const $style = useCssModule();
@ -95,6 +106,7 @@ const props = withDefaults(
}, },
); );
const vueFlowStore = useVueFlow({ id: props.id, deleteKeyCode: null });
const { const {
getSelectedNodes: selectedNodes, getSelectedNodes: selectedNodes,
addSelectedNodes, addSelectedNodes,
@ -112,9 +124,11 @@ const {
findNode, findNode,
onNodesInitialized, onNodesInitialized,
viewport, viewport,
} = useVueFlow({ id: props.id, deleteKeyCode: null }); onInit,
} = vueFlowStore;
const isPaneReady = ref(false); const isPaneReady = ref(false);
const { addTouchListeners, removeTouchListeners } = useTouchEventsInVueFlow(vueFlowStore);
const classes = computed(() => ({ const classes = computed(() => ({
[$style.canvas]: true, [$style.canvas]: true,
@ -488,6 +502,14 @@ onNodesInitialized((nodes) => {
void onFitView(); void onFitView();
}); });
onInit(() => {
addTouchListeners();
});
onBeforeUnmount(() => {
removeTouchListeners();
});
watch(() => props.readOnly, setReadonly, { watch(() => props.readOnly, setReadonly, {
immediate: true, immediate: true,
}); });

View file

@ -0,0 +1,60 @@
import { ref } from 'vue';
import type { VueFlowStore } from '@vue-flow/core';
export const useTouchEventsInVueFlow = (vueFlowStore: VueFlowStore) => {
const isPanning = ref(false);
const startX = ref(0);
const startY = ref(0);
const handleTouchStart = (event: TouchEvent) => {
const touch = event.touches[0];
startX.value = touch.clientX;
startY.value = touch.clientY;
if (event.touches.length > 1) {
isPanning.value = true;
}
};
const handleTouchMove = (event: TouchEvent) => {
event.preventDefault();
event.stopPropagation();
if (isPanning.value && vueFlowStore.vueFlowRef.value) {
const touch = event.touches[0];
const x = touch.clientX - startX.value;
const y = touch.clientY - startY.value;
vueFlowStore.panBy({ x, y });
startX.value = touch.clientX;
startY.value = touch.clientY;
}
};
const handleTouchEnd = () => {
isPanning.value = false;
};
const addTouchListeners = () => {
const canvas = vueFlowStore.vueFlowRef.value;
if (canvas) {
canvas.addEventListener('touchstart', handleTouchStart);
canvas.addEventListener('touchmove', handleTouchMove);
canvas.addEventListener('touchend', handleTouchEnd);
}
};
const removeTouchListeners = () => {
const canvas = vueFlowStore.vueFlowRef.value;
if (canvas) {
canvas.removeEventListener('touchstart', handleTouchStart);
canvas.removeEventListener('touchmove', handleTouchMove);
canvas.removeEventListener('touchend', handleTouchEnd);
}
};
return {
addTouchListeners,
removeTouchListeners,
};
};