1- import React , { useEffect , useRef , useState } from 'react' ;
1+ import React , { useState } from 'react' ;
22import AlgorithmVisualization from './algorithm/AlgorithmVisualization' ;
33import Controls from './controls/Controls' ;
44import DraggableProgressBar from './controls/DraggableProgressBar' ;
@@ -17,14 +17,12 @@ interface AlgorithmRunnerProps {
1717}
1818
1919/**
20- * 算法运行器主组件
21- * 协调算法的输入、执行、控制和可视化
20+ * 算法运行器主组件 - 单屏幕固定布局
21+ * 所有区域默认展示,isRunning只控制内容填充
2222 */
2323const AlgorithmRunner : React . FC < AlgorithmRunnerProps > = ( {
2424 width = 800
2525} ) => {
26- const containerRef = useRef < HTMLDivElement > ( null ) ;
27- const [ visualizationHeight , setVisualizationHeight ] = useState ( 500 ) ;
2826 const [ isModalOpen , setIsModalOpen ] = useState ( false ) ;
2927
3028 const {
@@ -52,35 +50,26 @@ const AlgorithmRunner: React.FC<AlgorithmRunnerProps> = ({
5250 goToStep
5351 } = useAlgorithmState ( ) ;
5452
55- // 动态计算可视化区域的高度
56- useEffect ( ( ) => {
57- const updateHeight = ( ) => {
58- if ( containerRef . current ) {
59- const windowHeight = window . innerHeight ;
60- const headerHeight = 80 ;
61- const inputHeight = 100 ;
62- const controlsHeight = 120 ;
63- const spacing = 60 ;
64-
65- const newHeight = windowHeight - headerHeight - inputHeight - controlsHeight - spacing ;
66- setVisualizationHeight ( Math . max ( newHeight , 300 ) ) ;
67- }
68- } ;
69-
70- updateHeight ( ) ;
71-
72- const timers = [
73- setTimeout ( updateHeight , 100 ) ,
74- setTimeout ( updateHeight , 300 )
75- ] ;
76-
77- window . addEventListener ( 'resize' , updateHeight ) ;
78-
79- return ( ) => {
80- window . removeEventListener ( 'resize' , updateHeight ) ;
81- timers . forEach ( timer => clearTimeout ( timer ) ) ;
82- } ;
83- } , [ isRunning ] ) ;
53+ // 使用播放控制钩子
54+ usePlaybackControls ( {
55+ isPlaying,
56+ playbackSpeed,
57+ onStepForward : stepForward ,
58+ isAtEnd,
59+ onPlaybackEnd : ( ) => setIsPlaying ( false )
60+ } ) ;
61+
62+ // 使用键盘控制钩子
63+ useKeyboardControls ( {
64+ isRunning,
65+ canGoBack,
66+ canGoForward,
67+ isPlaying,
68+ onStepBack : stepBackward ,
69+ onStepForward : stepForward ,
70+ onPlayPause : togglePlayPause ,
71+ onReset : resetToFirstStep
72+ } ) ;
8473
8574 // 构建变量值映射用于代码显示
8675 const variableValues : { [ key : string ] : string } = currentState ? {
@@ -93,8 +82,8 @@ const AlgorithmRunner: React.FC<AlgorithmRunnerProps> = ({
9382 } : { } ;
9483
9584 return (
96- < div className = "algorithm-runner" ref = { containerRef } >
97- { /* 头部导航 */ }
85+ < div className = "algorithm-runner" >
86+ { /* 头部导航 - 固定高度 */ }
9887 < Header onShowAlgorithmIdea = { ( ) => setIsModalOpen ( true ) } />
9988
10089 { /* 算法思路弹窗 */ }
@@ -103,7 +92,7 @@ const AlgorithmRunner: React.FC<AlgorithmRunnerProps> = ({
10392 onClose = { ( ) => setIsModalOpen ( false ) }
10493 />
10594
106- { /* 紧凑数据输入 */ }
95+ { /* 输入面板 - 固定高度 */ }
10796 < div className = "input-section" >
10897 < CompactInputPanel
10998 onInputChange = { handleInputChange }
@@ -117,58 +106,54 @@ const AlgorithmRunner: React.FC<AlgorithmRunnerProps> = ({
117106 />
118107 </ div >
119108
120- { /* 主内容区:画布 + 代码 */ }
121- { isRunning && (
122- < div className = "main-content" >
123- { /* 左侧画布 */ }
124- < div className = "canvas-section" >
125- < AlgorithmVisualization
126- inputString = { inputString }
127- currentState = { currentState }
128- width = { width }
129- height = { visualizationHeight }
130- currentStateIndex = { currentStateIndex }
131- totalSteps = { stateHistory . length }
132- />
133- </ div >
134-
135- { /* 右侧代码 */ }
136- < div className = "code-section" >
137- < CodeDisplay
138- currentStep = { currentStateIndex }
139- variableValues = { variableValues }
140- />
141- </ div >
142- </ div >
143- ) }
144-
145- { /* 底部控制区 */ }
146- { isRunning && (
147- < div className = "bottom-controls" >
148- { /* 可拖拽进度条 */ }
149- < DraggableProgressBar
150- currentStep = { currentStateIndex }
109+ { /* 主内容区:画布 + 代码 - 固定高度填充剩余空间 */ }
110+ < div className = "main-content" >
111+ { /* 左侧画布 - 始终展示 */ }
112+ < div className = "canvas-section" >
113+ < AlgorithmVisualization
114+ inputString = { inputString }
115+ currentState = { currentState }
116+ width = { width }
117+ height = { 0 }
118+ currentStateIndex = { currentStateIndex }
151119 totalSteps = { stateHistory . length }
152- onStepChange = { goToStep }
153120 />
121+ </ div >
154122
155- { /* 播放控制 */ }
156- < Controls
157- onPrev = { stepBackward }
158- onNext = { stepForward }
159- onPlay = { playAlgorithm }
160- onPause = { pauseAlgorithm }
161- onReset = { resetToFirstStep }
162- isPlaying = { isPlaying }
163- canGoBack = { canGoBack }
164- canGoForward = { canGoForward }
165- playbackSpeed = { playbackSpeed }
166- onSpeedChange = { handleSpeedChange }
123+ { /* 右侧代码 - 始终展示 */ }
124+ < div className = "code-section" >
125+ < CodeDisplay
167126 currentStep = { currentStateIndex }
168- totalSteps = { stateHistory . length }
127+ variableValues = { variableValues }
169128 />
170129 </ div >
171- ) }
130+ </ div >
131+
132+ { /* 底部控制区 - 固定高度 */ }
133+ < div className = "bottom-controls" >
134+ { /* 可拖拽进度条 - 无数据时禁用 */ }
135+ < DraggableProgressBar
136+ currentStep = { currentStateIndex }
137+ totalSteps = { stateHistory . length }
138+ onStepChange = { goToStep }
139+ />
140+
141+ { /* 播放控制 - 无数据时禁用 */ }
142+ < Controls
143+ onPrev = { stepBackward }
144+ onNext = { stepForward }
145+ onPlay = { playAlgorithm }
146+ onPause = { pauseAlgorithm }
147+ onReset = { resetToFirstStep }
148+ isPlaying = { isPlaying }
149+ canGoBack = { canGoBack && isRunning }
150+ canGoForward = { canGoForward && isRunning }
151+ playbackSpeed = { playbackSpeed }
152+ onSpeedChange = { handleSpeedChange }
153+ currentStep = { currentStateIndex }
154+ totalSteps = { stateHistory . length }
155+ />
156+ </ div >
172157
173158 { /* 微信悬浮球 */ }
174159 < WeChatFloatButton />
0 commit comments