@@ -43,6 +43,8 @@ export const LibroCellsOutputRender: React.FC<{
4343 const parentRef = useRef ( null ) ;
4444 const listRef = useRef < List | null > ( null ) ;
4545 const noEditorAreaRef = useRef < HTMLDivElement | null > ( null ) ;
46+ const scrollTopRef = useRef ( 0 ) ;
47+ const viewportHeightRef = useRef ( 0 ) ;
4648
4749 const [ editorsOffset , setEditorsOffset ] = useState < number [ ] > ( [ ] ) ;
4850
@@ -128,13 +130,38 @@ export const LibroCellsOutputRender: React.FC<{
128130 }
129131
130132 libroView . model . onScrollToCellView ( ( params : ScrollParams ) => {
131- // listRef.current!.scrollToRow(index);
132- listRef . current ! . scrollToCellPosition ( params . cellIndex , params . cellOffset ) ;
133+ const index = params . cellIndex ;
134+ const offset = params . cellOffset || 0 ;
135+ const top = ( editorsOffset [ index ] || 0 ) + offset ;
136+ const height = ( noEditorAreaHeight [ index ] || 0 ) + ( editorAreaHeight [ index ] || 0 ) ;
137+ const viewportTop = scrollTopRef . current ;
138+ const viewportHeight = viewportHeightRef . current ;
139+
140+ if ( viewportHeight && height ) {
141+ if ( top > viewportTop && top + height < viewportTop + viewportHeight ) {
142+ // 在可视范围内就不需要滚动
143+ return ;
144+ }
145+ if ( top < viewportTop ) {
146+ listRef . current ! . scrollToCellPosition ( index , offset ) ;
147+ } else {
148+ const prevCellNoEditorHeight = noEditorAreaHeight [ index - 1 ] || 0 ;
149+ const prevCellEditorHeight = editorAreaHeight [ index - 1 ] || 0 ;
150+ const centerOffset =
151+ offset -
152+ viewportHeight / 2 -
153+ ( prevCellNoEditorHeight - prevCellEditorHeight ) ;
154+ listRef . current ! . scrollToCellPosition ( index , centerOffset ) ; // 把目标 cell 的顶部放到视窗的中间位置
155+ }
156+ } else {
157+ listRef . current ! . scrollToCellPosition ( index , offset ) ;
158+ }
133159 } ) ;
160+
134161 return ( ) => {
135162 libroView . model . disposeScrollToCellViewEmitter ( ) ;
136163 } ;
137- } , [ listRef , libroView ] ) ;
164+ } , [ listRef , libroView , editorsOffset , noEditorAreaHeight , editorAreaHeight ] ) ;
138165
139166 // 在Cell的高度变化时,触发重新计算所有Cell的高度偏移值
140167 useEffect ( ( ) => {
@@ -166,6 +193,7 @@ export const LibroCellsOutputRender: React.FC<{
166193 return (
167194 < AutoSizer style = { { height : '100%' , width : '100%' } } ref = { parentRef } >
168195 { ( { width, height } : { width : number ; height : number } ) => {
196+ viewportHeightRef . current = height ;
169197 return (
170198 < List
171199 ref = { listRef }
@@ -188,6 +216,8 @@ export const LibroCellsOutputRender: React.FC<{
188216 scrollTop : number ;
189217 scrollingContainer : Element ;
190218 } ) => {
219+ scrollTopRef . current = scrollParams . scrollTop ;
220+ viewportHeightRef . current = scrollParams . clientHeight ;
191221 libroView . cellScrollEmitter . fire ( {
192222 scrollingContainer : scrollParams . scrollingContainer ,
193223 scrollTop : scrollParams . scrollTop ,
0 commit comments