11<script setup lang="ts">
22import { curveBasis , line } from " d3" ;
3- import { computed } from " vue" ;
3+ import { computed , type PropType } from " vue" ;
44
55import { useWorkflowStores } from " @/composables/workflowStores" ;
66import { getConnectionId } from " @/stores/workflowConnectionStore" ;
77import type { TerminalPosition } from " @/stores/workflowEditorStateStore" ;
88import type { Connection } from " @/stores/workflowStoreTypes" ;
99
10- interface Props {
11- id: string ;
12- connection: Connection ;
13- terminalPosition? : TerminalPosition | null ;
14- flowing? : boolean ;
15- breathing? : boolean ;
16- }
17-
18- const props = withDefaults (defineProps <Props >(), {
19- terminalPosition: null ,
20- flowing: false ,
21- breathing: false ,
10+ const props = defineProps ({
11+ id: String ,
12+ connection: {
13+ type: Object as PropType <Connection >,
14+ required: true ,
15+ },
16+ terminalPosition: {
17+ type: Object as PropType <TerminalPosition | null >,
18+ default: null ,
19+ },
2220});
2321
2422const ribbonMargin = 4 ;
@@ -166,24 +164,6 @@ const paths = computed(() => {
166164 return lines .map ((l ) => curve (l )! );
167165});
168166
169- // Estimate path length for animation timing on flowing connections
170- const estimatedPathLength = computed (() => {
171- if (! props .flowing ) {
172- return 0 ;
173- }
174-
175- if (! connectionPosition .value ) {
176- return 100 ;
177- }
178-
179- const deltaX = connectionPosition .value .endX - connectionPosition .value .startX ;
180- const deltaY = connectionPosition .value .endY - connectionPosition .value .startY ;
181- const straightDistance = Math .sqrt (deltaX * deltaX + deltaY * deltaY );
182-
183- // Add some extra length to account for curves
184- return Math .max (100 , straightDistance * 1.3 );
185- });
186-
187167const lineWidth = computed (() => {
188168 if (inputIsMappedOver .value || outputIsMappedOver .value ) {
189169 return 2 ;
@@ -203,10 +183,6 @@ const connectionClass = computed(() => {
203183 classList .push (" invalid" );
204184 }
205185
206- if (props .breathing ) {
207- classList .push (" breathing" );
208- }
209-
210186 return classList .join (" " );
211187});
212188
@@ -253,22 +229,6 @@ function keyForIndex(index: number) {
253229 :stroke-width =" lineWidth"
254230 fill =" none" >
255231 </path >
256-
257- <template v-if =" props .flowing " >
258- <path
259- v-for =" (path, index) in paths"
260- :key =" `particle-${keyForIndex(index)}`"
261- class =" connection-particle"
262- :d =" path"
263- :stroke-width =" lineWidth * 2"
264- :style =" {
265- '--path-length': `${estimatedPathLength}px`,
266- '--animation-duration': `${Math.max(2, estimatedPathLength / 80)}s`,
267- }"
268- stroke-linecap =" round"
269- fill =" none" >
270- </path >
271- </template >
272232 </g >
273233</template >
274234
@@ -287,45 +247,6 @@ function keyForIndex(index: number) {
287247 & .invalid {
288248 stroke : #{$brand-warning } ;
289249 }
290-
291- & .breathing {
292- animation : breathe 2s ease-in-out infinite ;
293- }
294- }
295-
296- .connection-particle {
297- stroke : white ;
298- stroke-dasharray : 0 calc (var (--path-length , 100px ) / 2 ) 0 var (--path-length , 100px );
299- animation : flow var (--animation-duration , 1s ) linear infinite ;
300- }
301- }
302-
303- @keyframes flow {
304- 0% {
305- stroke-dashoffset : 0 ;
306- }
307- 100% {
308- stroke-dashoffset : calc (-2 * var (--path-length , 100px ) - 8px );
309- }
310- }
311-
312- @keyframes breathe {
313- 0%,
314- 100% {
315- stroke-width : var (--stroke-width , 4px );
316- opacity : 0.8 ;
317- }
318- 25% {
319- stroke-width : calc (var (--stroke-width , 4px ) * 1.2 );
320- opacity : 0.9 ;
321- }
322- 50% {
323- stroke-width : calc (var (--stroke-width , 4px ) * 1.4 );
324- opacity : 1 ;
325- }
326- 75% {
327- stroke-width : calc (var (--stroke-width , 4px ) * 1.2 );
328- opacity : 0.9 ;
329250 }
330251}
331252 </style >
0 commit comments