@@ -7,6 +7,14 @@ import { renderEmptyState } from './renderEmptyState';
77import { renderLinkedLists } from './renderLinkedLists' ;
88import { renderIntersection } from './renderIntersection' ;
99import { addPointersIntersectEffect } from '../../../../utils/d3utils/pointers' ;
10+ import {
11+ addPointerAHighlight ,
12+ addPointerBHighlight ,
13+ addIntersectionHighlight ,
14+ addNodeSelectedEffect ,
15+ addPointersIntersectionEffect
16+ } from '../../../../utils/d3utils/pointers' ;
17+ import { collectNodePositions , applyAnimationEffects } from './renderAnimations' ;
1018
1119/**
1220 * 渲染可视化器
@@ -153,6 +161,15 @@ export const renderVisualizer = (
153161 // @ts -ignore - 绕过TS类型检查,确保调用正确的重载版本
154162 renderLinkedLists ( renderParams ) ;
155163
164+ // 在渲染链表之后、添加各种特效之前,收集节点位置
165+ const nodePositions = collectNodePositions (
166+ nodeInfo ,
167+ leftOffset ,
168+ nodeSpacing ,
169+ topRowY ,
170+ bottomRowY
171+ ) ;
172+
156173 // 渲染相交部分的连接线 - 使用与参考图类似的方式连接
157174 if ( nodeInfo . hasIntersection && nodeInfo . intersectionNodes . length > 0 ) {
158175 // 获取链表A和B的最后节点位置
@@ -666,113 +683,18 @@ export const renderVisualizer = (
666683 . attr ( 'd' , `M${ - arrowSize } ,${ lineEndY - arrowSize } L0,${ lineEndY } L${ arrowSize } ,${ lineEndY - arrowSize } Z` )
667684 . attr ( 'fill' , '#9b59b6' ) ;
668685
669- // 标记指针B已经被渲染
686+ // 标记指针B已被渲染
670687 renderedPointers . pointerB . add ( currentNodeB ) ;
671688 }
672689 }
673690
674- // 添加指针相交效果
675- if ( currentNodeA && currentNodeB && currentNodeA === currentNodeB && nodeAX > 0 && nodeAY > 0 ) {
676- // 检查两个指针是否都还没有被渲染
677- const needToRenderA = ! renderedPointers . pointerA . has ( currentNodeA ) ;
678- const needToRenderB = ! renderedPointers . pointerB . has ( currentNodeB ) ;
679-
680- // 如果两个指针中至少有一个还没有被渲染,就创建节点组
681- if ( needToRenderA || needToRenderB ) {
682- // 为节点创建一个固定位置的组
683- const nodeGroup = svg . append ( 'g' )
684- . attr ( 'transform' , `translate(${ nodeAX } , ${ nodeAY } )` ) ;
685-
686- // 计算指针标签的位置和大小
687- const pointerRadius = nodeRadius * 0.6 ; // 指针圆圈的半径
688- const pointerDistance = nodeRadius * 2.5 ; // 指针距离节点中心的距离
689-
690- // 只有在指针A还没有被渲染时才添加指针A
691- if ( needToRenderA ) {
692- // 1. 添加指针A的圆圈和标签 - 放在上方
693- const pointerGroupA = nodeGroup . append ( 'g' )
694- . attr ( 'transform' , `translate(0, ${ - pointerDistance } )` ) ;
695-
696- pointerGroupA . append ( 'circle' )
697- . attr ( 'r' , pointerRadius )
698- . attr ( 'fill' , '#3498db' )
699- . attr ( 'stroke' , 'white' )
700- . attr ( 'stroke-width' , 2 ) ;
701-
702- pointerGroupA . append ( 'text' )
703- . attr ( 'text-anchor' , 'middle' )
704- . attr ( 'dominant-baseline' , 'middle' )
705- . attr ( 'fill' , 'white' )
706- . attr ( 'font-size' , `${ fontSize * 0.7 } px` )
707- . attr ( 'font-weight' , 'bold' )
708- . text ( 'A' ) ;
709-
710- // 添加指针A的垂直线和箭头
711- const lineStartY_A = - pointerDistance + pointerRadius ;
712- const lineEndY_A = - nodeRadius ;
713-
714- // 画主线
715- nodeGroup . append ( 'line' )
716- . attr ( 'x1' , 0 )
717- . attr ( 'y1' , lineStartY_A )
718- . attr ( 'x2' , 0 )
719- . attr ( 'y2' , lineEndY_A )
720- . attr ( 'stroke' , '#3498db' )
721- . attr ( 'stroke-width' , 2.5 ) ;
722-
723- // 添加三角形箭头
724- const arrowSize = 8 ;
725- nodeGroup . append ( 'path' )
726- . attr ( 'd' , `M${ - arrowSize } ,${ lineEndY_A + arrowSize } L0,${ lineEndY_A } L${ arrowSize } ,${ lineEndY_A + arrowSize } Z` )
727- . attr ( 'fill' , '#3498db' ) ;
728-
729- // 标记指针A已被渲染
730- renderedPointers . pointerA . add ( currentNodeA ) ;
731- }
732-
733- // 只有在指针B还没有被渲染时才添加指针B
734- if ( needToRenderB ) {
735- // 2. 添加指针B的圆圈和标签 - 放在下方
736- const pointerGroupB = nodeGroup . append ( 'g' )
737- . attr ( 'transform' , `translate(0, ${ pointerDistance } )` ) ;
738-
739- pointerGroupB . append ( 'circle' )
740- . attr ( 'r' , pointerRadius )
741- . attr ( 'fill' , '#9b59b6' )
742- . attr ( 'stroke' , 'white' )
743- . attr ( 'stroke-width' , 2 ) ;
744-
745- pointerGroupB . append ( 'text' )
746- . attr ( 'text-anchor' , 'middle' )
747- . attr ( 'dominant-baseline' , 'middle' )
748- . attr ( 'fill' , 'white' )
749- . attr ( 'font-size' , `${ fontSize * 0.7 } px` )
750- . attr ( 'font-weight' , 'bold' )
751- . text ( 'B' ) ;
752-
753- // 添加指针B的垂直线和箭头
754- const lineStartY_B = pointerDistance - pointerRadius ;
755- const lineEndY_B = nodeRadius ;
756-
757- // 画主线
758- nodeGroup . append ( 'line' )
759- . attr ( 'x1' , 0 )
760- . attr ( 'y1' , lineStartY_B )
761- . attr ( 'x2' , 0 )
762- . attr ( 'y2' , lineEndY_B )
763- . attr ( 'stroke' , '#9b59b6' )
764- . attr ( 'stroke-width' , 2.5 ) ;
765-
766- // 添加三角形箭头
767- const arrowSize = 8 ;
768- nodeGroup . append ( 'path' )
769- . attr ( 'd' , `M${ - arrowSize } ,${ lineEndY_B - arrowSize } L0,${ lineEndY_B } L${ arrowSize } ,${ lineEndY_B - arrowSize } Z` )
770- . attr ( 'fill' , '#9b59b6' ) ;
771-
772- // 标记指针B已被渲染
773- renderedPointers . pointerB . add ( currentNodeB ) ;
774- }
775- }
691+ // 处理指针A和B在相同位置的情况
692+ if ( currentNodeA && currentNodeB && currentNodeA === currentNodeB ) {
693+ // 添加相交效果
694+ addPointersIntersectEffect ( svg , nodeAX , nodeAY , 1.2 ) ;
776695 }
696+
697+ // 在所有渲染完成后,添加动画效果
698+ applyAnimationEffects ( svg , currentNodeA , currentNodeB , nodePositions , nodeRadius , scale ) ;
777699 }
778700} ;
0 commit comments