Mentions légales du service

Skip to content
Snippets Groups Projects

Resolve "Limiting number of edges per handle and color indication"

Files
7
<script setup lang="ts">
<script setup lang="ts">
import { MarkerType, Position, connectionExists, getSimpleBezierPath, useVueFlow } from '@vue-flow/core';
import { Position, getSimpleBezierPath } from '@vue-flow/core';
import { computed, reactive, ref, watch } from 'vue';
import { computed } from 'vue';
const props = defineProps({
const props = defineProps({
sourceX: {
sourceX: {
@@ -29,125 +29,8 @@ const props = defineProps({
@@ -29,125 +29,8 @@ const props = defineProps({
},
},
});
});
const { getNodes, connectionStartHandle, onConnectEnd, addEdges, edges } = useVueFlow( { id: 'main' });
const closest = reactive({
node: null,
handle: null,
startHandle: connectionStartHandle.value,
});
const canSnap = ref(false);
const HIGHLIGHT_COLOR = '#f59e0b';
const SNAP_HIGHLIGHT_COLOR = '#00B3B9';
const MIN_DISTANCE = 75;
const SNAP_DISTANCE = 50;
watch([() => props.targetY, () => props.targetX], (_, __, onCleanup) => {
const closestNode = getNodes.value.reduce(
(res, n) => {
if (n.id !== connectionStartHandle.value?.nodeId) {
const dx = props.targetX - (n.computedPosition.x + n.dimensions.width / 2);
const dy = props.targetY - (n.computedPosition.y + n.dimensions.height / 2);
const d = Math.sqrt(dx * dx + dy * dy);
if (d < res.distance && d < MIN_DISTANCE) {
res.distance = d;
res.node = n;
}
}
return res;
},
{
distance: Number.MAX_VALUE,
node: null,
},
);
if (!closestNode.node) return;
canSnap.value = closestNode.distance < SNAP_DISTANCE;
const type = connectionStartHandle.value.type === 'source' ? 'target' : 'source';
const closestHandle = closestNode.node.handleBounds[type]?.reduce((prev, curr) => {
const prevDistance = Math.sqrt((prev.x - props.targetX) ** 2 + (prev.y - props.targetY) ** 2);
const currDistance = Math.sqrt((curr.x - props.targetX) ** 2 + (curr.y - props.targetY) ** 2);
return prevDistance < currDistance ? prev : curr;
});
if (
connectionExists(
{
source: connectionStartHandle.value.nodeId,
sourceHandle: connectionStartHandle.value.handleId,
target: closestNode.node.id,
targetHandle: closestHandle.id,
},
edges.value,
)
)
return;
if (closestHandle) {
const el = document.querySelector(`[data-handleid='${closestHandle.id}']`) as HTMLElement;
const prevStyle = el.style.backgroundColor;
el.style.backgroundColor = canSnap.value ? SNAP_HIGHLIGHT_COLOR : HIGHLIGHT_COLOR;
closest.node = closestNode.node;
closest.handle = closestHandle;
onCleanup(() => {
el.style.backgroundColor = prevStyle;
closest.node = null;
closest.handle = null;
});
}
});
// const path = computed(() => getBezierPath({sourceX: props.sourceX, sourceY: props.sourceY, sourcePosition: props.sourcePosition as Position, targetX: props.targetX, targetY: props.targetY, targetPosition: props.targetPosition as Position, curvature: 0.5}));
const path = computed(() => getSimpleBezierPath({sourceX: props.sourceX, sourceY: props.sourceY, sourcePosition: props.sourcePosition as Position, targetX: props.targetX, targetY: props.targetY, targetPosition: props.targetPosition as Position}));
const path = computed(() => getSimpleBezierPath({sourceX: props.sourceX, sourceY: props.sourceY, sourcePosition: props.sourcePosition as Position, targetX: props.targetX, targetY: props.targetY, targetPosition: props.targetPosition as Position}));
onConnectEnd(() => {
if (closest.startHandle && closest.handle && closest.node) {
if (canSnap.value) {
addEdges([
{
sourceHandle: closest.startHandle.handleId,
source: closest.startHandle.nodeId,
target: closest.node.id,
targetHandle: closest.handle.id,
updatable: true,
style: { stroke: '#384257', strokeWidth: 2.5 },
markerEnd: { type: MarkerType.ArrowClosed, color: '#384257' },
},
]);
// document.querySelector('.vue-flow__handle-' + closest.handle.id)?.classList.add('connected');
// document.querySelector('.vue-flow__handle-' + closest.startHandle.handleId)?.classList.add('connected');
// console.log(closest.startHandle);
// console.log(closest.handle);
}
}
});
const strokeColor = computed(() => {
if (canSnap.value) {
return SNAP_HIGHLIGHT_COLOR;
}
if (closest.node) {
return HIGHLIGHT_COLOR;
}
return '#222';
});
</script>
</script>
<template>
<template>
@@ -162,8 +45,8 @@ const strokeColor = computed(() => {
@@ -162,8 +45,8 @@ const strokeColor = computed(() => {
<circle
<circle
:cx="targetX"
:cx="targetX"
:cy="targetY"
:cy="targetY"
fill="#fff"
fill="#384257"
:stroke="strokeColor"
stroke="#384257"
:r="3"
:r="3"
:stroke-width="2.5"
:stroke-width="2.5"
/>
/>
Loading