@@ -107,28 +107,89 @@ md.use(window.markdownitContainer, 'danger', { render: renderContainer });
107107
108108var preventSyncScroll = false ;
109109
110- //var editorScrollThrottle = 100;
110+ var editScrollThrottle = 1 ;
111+ var viewScrollThrottle = 20 ;
111112var buildMapThrottle = 100 ;
112113
113114var viewScrolling = false ;
114115var viewScrollingDelay = 200 ;
115116var viewScrollingTimer = null ;
116117
117- //editor.on('scroll', _.throttle(syncScrollToView, editorScrollThrottle));
118+ var editScrolling = false ;
119+ var editScrollingDelay = 100 ;
120+ var editScrollingTimer = null ;
121+
118122if ( editor . getOption ( 'scrollbarStyle' ) === 'native' ) {
119- ui . area . codemirrorScroll . on ( 'scroll' , syncScrollToView ) ;
123+ ui . area . codemirrorScroll . on ( 'scroll' , _ . throttle ( syncScrollToView , editScrollThrottle ) ) ;
120124} else {
121- editor . on ( 'scroll' , syncScrollToView ) ;
125+ editor . on ( 'scroll' , _ . throttle ( syncScrollToView , editScrollThrottle ) ) ;
122126}
123- ui . area . view . on ( 'scroll' , function ( ) {
127+ ui . area . view . on ( 'scroll' , _ . throttle ( syncScrollToEdit , viewScrollThrottle ) ) ;
128+
129+ var preventViewScroll = false ;
130+
131+ function syncScrollToEdit ( e ) {
132+ if ( currentMode != modeType . both ) return ;
133+ if ( preventViewScroll ) {
134+ if ( typeof preventViewScroll === 'number' ) {
135+ preventViewScroll -- ;
136+ } else {
137+ preventViewScroll = false ;
138+ }
139+ return ;
140+ }
141+ if ( ! scrollMap || ! lineHeightMap ) {
142+ buildMap ( true ) ;
143+ return ;
144+ }
145+ if ( editScrolling ) return ;
146+ var scrollTop = ui . area . view [ 0 ] . scrollTop ;
147+ var lineIndex = 0 ;
148+ for ( var i = 0 , l = scrollMap . length ; i < l ; i ++ ) {
149+ if ( scrollMap [ i ] > scrollTop ) {
150+ break ;
151+ } else {
152+ lineIndex = i ;
153+ }
154+ }
155+ var lineNo = 0 ;
156+ var lineDiff = 0 ;
157+ for ( var i = 0 , l = lineHeightMap . length ; i < l ; i ++ ) {
158+ if ( lineHeightMap [ i ] > lineIndex ) {
159+ break ;
160+ } else {
161+ lineNo = lineHeightMap [ i ] ;
162+ lineDiff = lineHeightMap [ i + 1 ] - lineNo ;
163+ }
164+ }
165+
166+ var scrollInfo = editor . getScrollInfo ( ) ;
167+ var textHeight = editor . defaultTextHeight ( ) ;
168+ var posTo = 0 ;
169+ var topDiffPercent = 0 ;
170+ var posToNextDiff = 0 ;
171+ var preLastLineHeight = scrollInfo . height - scrollInfo . clientHeight - textHeight ;
172+ var preLastLineNo = Math . round ( preLastLineHeight / textHeight ) ;
173+
174+ if ( scrollInfo . height > scrollInfo . clientHeight && lineNo >= preLastLineNo ) {
175+ posTo = preLastLineHeight ;
176+ topDiffPercent = ( scrollTop - scrollMap [ preLastLineNo ] ) / ( viewBottom - scrollMap [ preLastLineNo ] ) ;
177+ posToNextDiff = Math . ceil ( textHeight * topDiffPercent ) ;
178+ } else {
179+ posTo = lineNo * textHeight ;
180+ topDiffPercent = ( scrollTop - scrollMap [ lineNo ] ) / ( scrollMap [ lineNo + lineDiff ] - scrollMap [ lineNo ] ) ;
181+ posToNextDiff = Math . ceil ( textHeight * lineDiff * topDiffPercent ) ;
182+ }
183+
184+ editor . scrollTo ( 0 , posTo + posToNextDiff ) ;
185+ preventSyncScroll = true ;
186+
124187 viewScrolling = true ;
125188 clearTimeout ( viewScrollingTimer ) ;
126189 viewScrollingTimer = setTimeout ( function ( ) {
127190 viewScrolling = false ;
128191 } , viewScrollingDelay ) ;
129- } ) ;
130- //editor.on('scroll', _.debounce(syncScrollToView, syncScrollDelay));
131- //ui.area.view.on('scroll', _.debounce(syncScrollToEdit, 50));
192+ }
132193
133194var scrollMap , lineHeightMap , viewTop , viewBottom ;
134195
@@ -291,19 +352,12 @@ function syncScrollToView(event, _lineNo) {
291352 if ( viewScrolling ) return ;
292353 posTo = scrollMap [ lineHeightMap [ _lineNo ] ] ;
293354 }
294- var posDiff = Math . abs ( ui . area . view . scrollTop ( ) - posTo ) ;
295- var duration = posDiff / 50 ;
296- ui . area . view . stop ( true , true ) . animate ( {
297- scrollTop : posTo
298- } , duration >= 100 ? duration : 100 , "linear" ) ;
299- /*
300- if (posDiff > scrollInfo.clientHeight / 5) {
301- var duration = posDiff / 50;
302- ui.area.view.stop(true, true).animate({
303- scrollTop: posTo
304- }, duration >= 100 ? duration : 100, "linear");
305- } else {
306- ui.area.view.stop(true, true).scrollTop(posTo);
307- }
308- */
355+ ui . area . view . stop ( true , true ) . scrollTop ( posTo ) ;
356+ preventViewScroll = true ;
357+
358+ editScrolling = true ;
359+ clearTimeout ( editScrollingTimer ) ;
360+ editScrollingTimer = setTimeout ( function ( ) {
361+ editScrolling = false ;
362+ } , editScrollingDelay ) ;
309363}
0 commit comments