Improve syncscroll performance and accuracy with few UX tweaks
This commit is contained in:
		
							parent
							
								
									20fbc9957f
								
							
						
					
					
						commit
						2c60f0dd67
					
				| @ -713,6 +713,14 @@ $(window).error(function () { | ||||
|     //setNeedRefresh();
 | ||||
| }); | ||||
| 
 | ||||
| function autoSyncscroll() { | ||||
|     if (editorHasFocus()) { | ||||
|         syncScrollToView(); | ||||
|     } else { | ||||
|         syncScrollToEdit(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| var windowResizeDebounce = 200; | ||||
| var windowResize = _.debounce(windowResizeInner, windowResizeDebounce); | ||||
| 
 | ||||
| @ -727,11 +735,7 @@ function windowResizeInner(callback) { | ||||
|         if (editor.getOption('scrollbarStyle') === 'native') { | ||||
|             setTimeout(function () { | ||||
|                 clearMap(); | ||||
|                 if (editorHasFocus()) { | ||||
|                     syncScrollToView(); | ||||
|                 } else { | ||||
|                     syncScrollToEdit(); | ||||
|                 } | ||||
|                 autoSyncscroll(); | ||||
|                 updateScrollspy(); | ||||
|                 if (callback && typeof callback === 'function') | ||||
|                     callback(); | ||||
| @ -741,11 +745,7 @@ function windowResizeInner(callback) { | ||||
|             editor.setOption('viewportMargin', Infinity); | ||||
|             setTimeout(function () { | ||||
|                 clearMap(); | ||||
|                 if (editorHasFocus()) { | ||||
|                     syncScrollToView(); | ||||
|                 } else { | ||||
|                     syncScrollToEdit(); | ||||
|                 } | ||||
|                 autoSyncscroll(); | ||||
|                 editor.setOption('viewportMargin', viewportMargin); | ||||
|                 //add or update user cursors
 | ||||
|                 for (var i = 0; i < onlineUsers.length; i++) { | ||||
| @ -1029,12 +1029,12 @@ function changeMode(type) { | ||||
| 
 | ||||
|     if (lastMode == modeType.view && currentMode == modeType.both) { | ||||
|         preventSyncScrollToView = 2; | ||||
|         syncScrollToEdit(); | ||||
|         syncScrollToEdit(null, true); | ||||
|     } | ||||
|      | ||||
|     if (lastMode == modeType.edit && currentMode == modeType.both) { | ||||
|         preventSyncScrollToEdit = 2; | ||||
|         syncScrollToView(); | ||||
|         syncScrollToView(null, true); | ||||
|     } | ||||
|      | ||||
|     if (lastMode == modeType.both && currentMode != modeType.both) { | ||||
| @ -2458,10 +2458,10 @@ editor.on('beforeChange', function (cm, change) { | ||||
|         cmClient.editorAdapter.ignoreNextChange = true; | ||||
| }); | ||||
| editor.on('cut', function () { | ||||
|     windowResize(); //workaround for scrollMap
 | ||||
|     //na
 | ||||
| }); | ||||
| editor.on('paste', function () { | ||||
|     windowResize(); //workaround for scrollMap
 | ||||
|     //na
 | ||||
| }); | ||||
| editor.on('changes', function (cm, changes) { | ||||
|     updateHistory(); | ||||
| @ -2630,11 +2630,7 @@ function updateViewInner() { | ||||
|     clearMap(); | ||||
|     //buildMap();
 | ||||
|     updateTitleReminder(); | ||||
|     if (editorHasFocus()) { | ||||
|         syncScrollToView(); | ||||
|     } else { | ||||
|         syncScrollToEdit(); | ||||
|     } | ||||
|     autoSyncscroll(); | ||||
| } | ||||
| 
 | ||||
| var updateHistoryDebounce = 600; | ||||
|  | ||||
| @ -110,7 +110,7 @@ var syncscroll = true; | ||||
| var preventSyncScrollToEdit = false; | ||||
| var preventSyncScrollToView = false; | ||||
| 
 | ||||
| var editScrollThrottle = 2; | ||||
| var editScrollThrottle = 10; | ||||
| var viewScrollThrottle = 10; | ||||
| var buildMapThrottle = 100; | ||||
| 
 | ||||
| @ -214,7 +214,7 @@ function buildMapInner(callback) { | ||||
| // sync view scroll progress to edit
 | ||||
| var viewScrollingTimer = null; | ||||
| 
 | ||||
| function syncScrollToEdit(e) { | ||||
| function syncScrollToEdit(event, preventAnimate) { | ||||
|     if (currentMode != modeType.both || !syncscroll) return; | ||||
|     if (preventSyncScrollToEdit) { | ||||
|         if (typeof preventSyncScrollToEdit === 'number') { | ||||
| @ -225,7 +225,9 @@ function syncScrollToEdit(e) { | ||||
|         return; | ||||
|     } | ||||
|     if (!scrollMap || !lineHeightMap) { | ||||
|         buildMap(syncScrollToEdit); | ||||
|         buildMap(function () { | ||||
|             syncScrollToEdit(event, preventAnimate); | ||||
|         }); | ||||
|         return; | ||||
|     } | ||||
|     if (editScrolling) return; | ||||
| @ -263,24 +265,28 @@ function syncScrollToEdit(e) { | ||||
|         posTo = preLastLineHeight; | ||||
|         topDiffPercent = (scrollTop - preLastLinePos) / (viewBottom - preLastLinePos); | ||||
|         posToNextDiff = textHeight * topDiffPercent; | ||||
|         posTo += Math.floor(posToNextDiff); | ||||
|         posTo += Math.ceil(posToNextDiff); | ||||
|     } else { | ||||
|         posTo = lineNo * textHeight; | ||||
|         topDiffPercent = (scrollTop - scrollMap[lineNo]) / (scrollMap[lineNo + lineDiff] - scrollMap[lineNo]); | ||||
|         posToNextDiff = textHeight * lineDiff * topDiffPercent; | ||||
|         posTo += Math.floor(posToNextDiff); | ||||
|         posTo += Math.ceil(posToNextDiff); | ||||
|     } | ||||
|      | ||||
|     if (preventAnimate) { | ||||
|         ui.area.codemirrorScroll.scrollTop(posTo); | ||||
|     } else { | ||||
|         var posDiff = Math.abs(scrollInfo.top - posTo); | ||||
|         var duration = posDiff / 50; | ||||
|         duration = duration >= 100 ? duration : 100; | ||||
|         ui.area.codemirrorScroll.stop(true, true).animate({ | ||||
|             scrollTop: posTo | ||||
|         }, duration, "linear"); | ||||
|     } | ||||
|      | ||||
|     viewScrolling = true; | ||||
|     clearTimeout(viewScrollingTimer); | ||||
|     viewScrollingTimer = setTimeout(viewScrollingTimeoutInner, duration * 1.2); | ||||
|     viewScrollingTimer = setTimeout(viewScrollingTimeoutInner, duration * 1.5); | ||||
| } | ||||
| 
 | ||||
| function viewScrollingTimeoutInner() { | ||||
| @ -290,7 +296,7 @@ function viewScrollingTimeoutInner() { | ||||
| // sync edit scroll progress to view
 | ||||
| var editScrollingTimer = null; | ||||
| 
 | ||||
| function syncScrollToView(event, _lineNo) { | ||||
| function syncScrollToView(event, preventAnimate) { | ||||
|     if (currentMode != modeType.both || !syncscroll) return; | ||||
|     if (preventSyncScrollToView) { | ||||
|         if (typeof preventSyncScrollToView === 'number') { | ||||
| @ -301,12 +307,13 @@ function syncScrollToView(event, _lineNo) { | ||||
|         return; | ||||
|     } | ||||
|     if (!scrollMap || !lineHeightMap) { | ||||
|         buildMap(syncScrollToView); | ||||
|         buildMap(function () { | ||||
|             syncScrollToView(event, preventAnimate); | ||||
|         }); | ||||
|         return; | ||||
|     } | ||||
|     if (viewScrolling) return; | ||||
|      | ||||
|     if (!_lineNo) { | ||||
|     var lineNo, posTo; | ||||
|     var topDiffPercent, posToNextDiff; | ||||
|     var scrollInfo = editor.getScrollInfo(); | ||||
| @ -325,20 +332,21 @@ function syncScrollToView(event, _lineNo) { | ||||
|         posToNextDiff = (scrollMap[lineNo + 1] - posTo) * topDiffPercent; | ||||
|         posTo += Math.floor(posToNextDiff); | ||||
|     } | ||||
|     } else { | ||||
|         posTo = scrollMap[lineHeightMap[_lineNo]]; | ||||
|     } | ||||
|      | ||||
|     if (preventAnimate) { | ||||
|         ui.area.view.scrollTop(posTo); | ||||
|     } else { | ||||
|         var posDiff = Math.abs(ui.area.view.scrollTop() - posTo); | ||||
|         var duration = posDiff / 50; | ||||
|         duration = duration >= 100 ? duration : 100; | ||||
|         ui.area.view.stop(true, true).animate({ | ||||
|             scrollTop: posTo | ||||
|         }, duration, "linear"); | ||||
|     } | ||||
|      | ||||
|     editScrolling = true; | ||||
|     clearTimeout(editScrollingTimer); | ||||
|     editScrollingTimer = setTimeout(editScrollingTimeoutInner, duration * 1.2); | ||||
|     editScrollingTimer = setTimeout(editScrollingTimeoutInner, duration * 1.5); | ||||
| } | ||||
| 
 | ||||
| function editScrollingTimeoutInner() { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user