Skip to content

Commit 396052a

Browse files
committed
添加递归调用可视化组件,显示递归进入/退出、值传递和返回等细节
1 parent 96817a1 commit 396052a

File tree

4 files changed

+633
-0
lines changed

4 files changed

+633
-0
lines changed
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
/* 递归调用可视化组件 */
2+
.recursion-call-visualizer {
3+
background: white;
4+
border-radius: 8px;
5+
padding: 12px;
6+
margin: 8px 0;
7+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
8+
border-left: 4px solid #2196F3;
9+
animation: slideIn 0.3s ease-out;
10+
}
11+
12+
@keyframes slideIn {
13+
from {
14+
opacity: 0;
15+
transform: translateX(-20px);
16+
}
17+
to {
18+
opacity: 1;
19+
transform: translateX(0);
20+
}
21+
}
22+
23+
/* 不同步骤类型的边框颜色 */
24+
.recursion-call-visualizer.initial {
25+
border-left-color: #2196F3;
26+
}
27+
28+
.recursion-call-visualizer.compare {
29+
border-left-color: #FF9800;
30+
}
31+
32+
.recursion-call-visualizer.check-null {
33+
border-left-color: #9C27B0;
34+
}
35+
36+
.recursion-call-visualizer.check-value {
37+
border-left-color: #F44336;
38+
}
39+
40+
.recursion-call-visualizer.check-subtree {
41+
border-left-color: #4CAF50;
42+
}
43+
44+
.recursion-call-visualizer.return {
45+
border-left-color: #607D8B;
46+
}
47+
48+
.recursion-call-visualizer.final {
49+
border-left-color: #E91E63;
50+
}
51+
52+
/* 进入和退出状态 */
53+
.recursion-call-visualizer.entering {
54+
background: linear-gradient(135deg, #E3F2FD 0%, #BBDEFB 100%);
55+
}
56+
57+
.recursion-call-visualizer.exiting {
58+
background: linear-gradient(135deg, #FFF3E0 0%, #FFE0B2 100%);
59+
}
60+
61+
/* 调用头部 */
62+
.call-header {
63+
display: flex;
64+
align-items: center;
65+
gap: 10px;
66+
margin-bottom: 8px;
67+
padding-bottom: 8px;
68+
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
69+
}
70+
71+
.call-icon {
72+
font-size: 20px;
73+
}
74+
75+
.call-action {
76+
font-weight: 600;
77+
font-size: 14px;
78+
color: #333;
79+
padding: 2px 8px;
80+
background: rgba(0, 0, 0, 0.05);
81+
border-radius: 4px;
82+
}
83+
84+
.call-depth {
85+
margin-left: auto;
86+
font-size: 12px;
87+
color: #666;
88+
background: #f0f0f0;
89+
padding: 2px 8px;
90+
border-radius: 10px;
91+
}
92+
93+
/* 调用主体 */
94+
.call-body {
95+
transition: padding-left 0.3s ease;
96+
}
97+
98+
.call-description {
99+
font-family: 'Consolas', 'Monaco', monospace;
100+
font-size: 13px;
101+
color: #1565C0;
102+
background: rgba(33, 150, 243, 0.1);
103+
padding: 8px 12px;
104+
border-radius: 4px;
105+
margin-bottom: 8px;
106+
}
107+
108+
/* 参数显示 */
109+
.call-params {
110+
display: flex;
111+
align-items: center;
112+
justify-content: center;
113+
gap: 12px;
114+
margin-top: 8px;
115+
}
116+
117+
.param {
118+
display: flex;
119+
flex-direction: column;
120+
align-items: center;
121+
padding: 8px 16px;
122+
border-radius: 8px;
123+
min-width: 80px;
124+
}
125+
126+
.param.left {
127+
background: linear-gradient(135deg, #FCE4EC 0%, #F8BBD9 100%);
128+
border: 1px solid #E91E63;
129+
}
130+
131+
.param.right {
132+
background: linear-gradient(135deg, #F3E5F5 0%, #E1BEE7 100%);
133+
border: 1px solid #9C27B0;
134+
}
135+
136+
.param-label {
137+
font-size: 11px;
138+
color: #666;
139+
margin-bottom: 4px;
140+
}
141+
142+
.param-value {
143+
font-size: 18px;
144+
font-weight: bold;
145+
font-family: 'Consolas', 'Monaco', monospace;
146+
}
147+
148+
.param.left .param-value {
149+
color: #C2185B;
150+
}
151+
152+
.param.right .param-value {
153+
color: #7B1FA2;
154+
}
155+
156+
.param-arrow {
157+
font-size: 24px;
158+
color: #FF9800;
159+
animation: pulse 1.5s infinite;
160+
}
161+
162+
@keyframes pulse {
163+
0%, 100% {
164+
transform: scale(1);
165+
opacity: 1;
166+
}
167+
50% {
168+
transform: scale(1.2);
169+
opacity: 0.7;
170+
}
171+
}
172+
173+
/* 返回值显示 */
174+
.return-value {
175+
display: flex;
176+
align-items: center;
177+
gap: 8px;
178+
margin-top: 10px;
179+
padding: 8px 12px;
180+
border-radius: 6px;
181+
font-weight: 600;
182+
}
183+
184+
.return-value.success {
185+
background: linear-gradient(135deg, #E8F5E9 0%, #C8E6C9 100%);
186+
color: #2E7D32;
187+
border: 1px solid #4CAF50;
188+
}
189+
190+
.return-value.failure {
191+
background: linear-gradient(135deg, #FFEBEE 0%, #FFCDD2 100%);
192+
color: #C62828;
193+
border: 1px solid #F44336;
194+
}
195+
196+
.return-arrow {
197+
font-size: 18px;
198+
animation: bounceLeft 0.5s ease-out;
199+
}
200+
201+
@keyframes bounceLeft {
202+
0% {
203+
transform: translateX(20px);
204+
opacity: 0;
205+
}
206+
50% {
207+
transform: translateX(-5px);
208+
}
209+
100% {
210+
transform: translateX(0);
211+
opacity: 1;
212+
}
213+
}
214+
215+
.return-text {
216+
font-family: 'Consolas', 'Monaco', monospace;
217+
font-size: 14px;
218+
}
219+
220+
/* 递归指示器 */
221+
.recursion-indicator {
222+
display: flex;
223+
align-items: center;
224+
gap: 8px;
225+
margin-top: 10px;
226+
padding-top: 10px;
227+
border-top: 1px dashed #ccc;
228+
}
229+
230+
.recursion-line {
231+
flex: 1;
232+
height: 2px;
233+
background: linear-gradient(90deg, #4CAF50, transparent);
234+
animation: expandLine 0.5s ease-out;
235+
}
236+
237+
@keyframes expandLine {
238+
from {
239+
width: 0;
240+
}
241+
to {
242+
width: 100%;
243+
}
244+
}
245+
246+
.recursion-text {
247+
font-size: 12px;
248+
color: #4CAF50;
249+
font-weight: 500;
250+
white-space: nowrap;
251+
}
252+
253+
/* 响应式调整 */
254+
@media (max-width: 768px) {
255+
.recursion-call-visualizer {
256+
padding: 10px;
257+
}
258+
259+
.call-params {
260+
flex-direction: column;
261+
gap: 8px;
262+
}
263+
264+
.param-arrow {
265+
transform: rotate(90deg);
266+
}
267+
268+
.param {
269+
width: 100%;
270+
}
271+
}

0 commit comments

Comments
 (0)