Add support of sync scrolling to edit area
This commit is contained in:
parent
f3418a619c
commit
bf1dc237a9
2 changed files with 81 additions and 35 deletions
|
@ -743,6 +743,7 @@ function windowResizeInner(callback) {
|
||||||
if (editor.getOption('scrollbarStyle') === 'native') {
|
if (editor.getOption('scrollbarStyle') === 'native') {
|
||||||
clearMap();
|
clearMap();
|
||||||
syncScrollToView();
|
syncScrollToView();
|
||||||
|
syncScrollToEdit();
|
||||||
updateScrollspy();
|
updateScrollspy();
|
||||||
if (callback && typeof callback === 'function')
|
if (callback && typeof callback === 'function')
|
||||||
callback();
|
callback();
|
||||||
|
@ -752,6 +753,7 @@ function windowResizeInner(callback) {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
clearMap();
|
clearMap();
|
||||||
syncScrollToView();
|
syncScrollToView();
|
||||||
|
syncScrollToEdit();
|
||||||
editor.setOption('viewportMargin', viewportMargin);
|
editor.setOption('viewportMargin', viewportMargin);
|
||||||
//add or update user cursors
|
//add or update user cursors
|
||||||
for (var i = 0; i < onlineUsers.length; i++) {
|
for (var i = 0; i < onlineUsers.length; i++) {
|
||||||
|
@ -822,7 +824,6 @@ function checkEditorScrollbar() {
|
||||||
// workaround simple scroll bar knob
|
// workaround simple scroll bar knob
|
||||||
// will get wrong position when editor height changed
|
// will get wrong position when editor height changed
|
||||||
var scrollInfo = editor.getScrollInfo();
|
var scrollInfo = editor.getScrollInfo();
|
||||||
if (!preventSyncScroll) preventSyncScroll = true;
|
|
||||||
editor.scrollTo(null, scrollInfo.top - 1);
|
editor.scrollTo(null, scrollInfo.top - 1);
|
||||||
editor.scrollTo(null, scrollInfo.top);
|
editor.scrollTo(null, scrollInfo.top);
|
||||||
}
|
}
|
||||||
|
@ -1027,15 +1028,6 @@ var unlockNavbar = _.debounce(function () {
|
||||||
$('.navbar').removeClass('locked');
|
$('.navbar').removeClass('locked');
|
||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
function syncScrollToEdit() {
|
|
||||||
if (!scrollMap || !lineHeightMap)
|
|
||||||
buildMapInner();
|
|
||||||
var scrollMapNearest = closestIndex(scrollMap, lastInfo.view.scroll.top);
|
|
||||||
var lineHeightMapNearest = closestIndex(lineHeightMap, scrollMapNearest);
|
|
||||||
var height = lineHeightMapNearest * defaultTextHeight;
|
|
||||||
editor.scrollTo(null, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
function closestIndex(arr, closestTo) {
|
function closestIndex(arr, closestTo) {
|
||||||
var closest = Math.max.apply(null, arr); //Get the highest number in arr in case it match nothing.
|
var closest = Math.max.apply(null, arr); //Get the highest number in arr in case it match nothing.
|
||||||
var index = 0;
|
var index = 0;
|
||||||
|
@ -2422,11 +2414,9 @@ editor.on('beforeChange', function (cm, change) {
|
||||||
cmClient.editorAdapter.ignoreNextChange = true;
|
cmClient.editorAdapter.ignoreNextChange = true;
|
||||||
});
|
});
|
||||||
editor.on('cut', function () {
|
editor.on('cut', function () {
|
||||||
preventSyncScroll = 3;
|
|
||||||
windowResize(); //workaround for scrollMap
|
windowResize(); //workaround for scrollMap
|
||||||
});
|
});
|
||||||
editor.on('paste', function () {
|
editor.on('paste', function () {
|
||||||
preventSyncScroll = 3;
|
|
||||||
windowResize(); //workaround for scrollMap
|
windowResize(); //workaround for scrollMap
|
||||||
});
|
});
|
||||||
editor.on('changes', function (cm, changes) {
|
editor.on('changes', function (cm, changes) {
|
||||||
|
@ -2596,6 +2586,8 @@ function updateViewInner() {
|
||||||
clearMap();
|
clearMap();
|
||||||
//buildMap();
|
//buildMap();
|
||||||
updateTitleReminder();
|
updateTitleReminder();
|
||||||
|
syncScrollToView();
|
||||||
|
syncScrollToEdit();
|
||||||
}
|
}
|
||||||
|
|
||||||
var updateHistoryDebounce = 600;
|
var updateHistoryDebounce = 600;
|
||||||
|
|
|
@ -107,28 +107,89 @@ md.use(window.markdownitContainer, 'danger', { render: renderContainer });
|
||||||
|
|
||||||
var preventSyncScroll = false;
|
var preventSyncScroll = false;
|
||||||
|
|
||||||
//var editorScrollThrottle = 100;
|
var editScrollThrottle = 1;
|
||||||
|
var viewScrollThrottle = 20;
|
||||||
var buildMapThrottle = 100;
|
var buildMapThrottle = 100;
|
||||||
|
|
||||||
var viewScrolling = false;
|
var viewScrolling = false;
|
||||||
var viewScrollingDelay = 200;
|
var viewScrollingDelay = 200;
|
||||||
var viewScrollingTimer = null;
|
var viewScrollingTimer = null;
|
||||||
|
|
||||||
//editor.on('scroll', _.throttle(syncScrollToView, editorScrollThrottle));
|
var editScrolling = false;
|
||||||
|
var editScrollingDelay = 100;
|
||||||
|
var editScrollingTimer = null;
|
||||||
|
|
||||||
if (editor.getOption('scrollbarStyle') === 'native') {
|
if (editor.getOption('scrollbarStyle') === 'native') {
|
||||||
ui.area.codemirrorScroll.on('scroll', syncScrollToView);
|
ui.area.codemirrorScroll.on('scroll', _.throttle(syncScrollToView, editScrollThrottle));
|
||||||
} else {
|
} else {
|
||||||
editor.on('scroll', syncScrollToView);
|
editor.on('scroll', _.throttle(syncScrollToView, editScrollThrottle));
|
||||||
}
|
}
|
||||||
ui.area.view.on('scroll', function () {
|
ui.area.view.on('scroll', _.throttle(syncScrollToEdit, viewScrollThrottle));
|
||||||
|
|
||||||
|
var preventViewScroll = false;
|
||||||
|
|
||||||
|
function syncScrollToEdit(e) {
|
||||||
|
if (currentMode != modeType.both) return;
|
||||||
|
if (preventViewScroll) {
|
||||||
|
if (typeof preventViewScroll === 'number') {
|
||||||
|
preventViewScroll--;
|
||||||
|
} else {
|
||||||
|
preventViewScroll = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!scrollMap || !lineHeightMap) {
|
||||||
|
buildMap(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (editScrolling) return;
|
||||||
|
var scrollTop = ui.area.view[0].scrollTop;
|
||||||
|
var lineIndex = 0;
|
||||||
|
for (var i = 0, l = scrollMap.length; i < l; i++) {
|
||||||
|
if (scrollMap[i] > scrollTop) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
lineIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var lineNo = 0;
|
||||||
|
var lineDiff = 0;
|
||||||
|
for (var i = 0, l = lineHeightMap.length; i < l; i++) {
|
||||||
|
if (lineHeightMap[i] > lineIndex) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
lineNo = lineHeightMap[i];
|
||||||
|
lineDiff = lineHeightMap[i + 1] - lineNo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var scrollInfo = editor.getScrollInfo();
|
||||||
|
var textHeight = editor.defaultTextHeight();
|
||||||
|
var posTo = 0;
|
||||||
|
var topDiffPercent = 0;
|
||||||
|
var posToNextDiff = 0;
|
||||||
|
var preLastLineHeight = scrollInfo.height - scrollInfo.clientHeight - textHeight;
|
||||||
|
var preLastLineNo = Math.round(preLastLineHeight / textHeight);
|
||||||
|
|
||||||
|
if (scrollInfo.height > scrollInfo.clientHeight && lineNo >= preLastLineNo) {
|
||||||
|
posTo = preLastLineHeight;
|
||||||
|
topDiffPercent = (scrollTop - scrollMap[preLastLineNo]) / (viewBottom - scrollMap[preLastLineNo]);
|
||||||
|
posToNextDiff = Math.ceil(textHeight * topDiffPercent);
|
||||||
|
} else {
|
||||||
|
posTo = lineNo * textHeight;
|
||||||
|
topDiffPercent = (scrollTop - scrollMap[lineNo]) / (scrollMap[lineNo + lineDiff] - scrollMap[lineNo]);
|
||||||
|
posToNextDiff = Math.ceil(textHeight * lineDiff * topDiffPercent);
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.scrollTo(0, posTo + posToNextDiff);
|
||||||
|
preventSyncScroll = true;
|
||||||
|
|
||||||
viewScrolling = true;
|
viewScrolling = true;
|
||||||
clearTimeout(viewScrollingTimer);
|
clearTimeout(viewScrollingTimer);
|
||||||
viewScrollingTimer = setTimeout(function () {
|
viewScrollingTimer = setTimeout(function () {
|
||||||
viewScrolling = false;
|
viewScrolling = false;
|
||||||
}, viewScrollingDelay);
|
}, viewScrollingDelay);
|
||||||
});
|
}
|
||||||
//editor.on('scroll', _.debounce(syncScrollToView, syncScrollDelay));
|
|
||||||
//ui.area.view.on('scroll', _.debounce(syncScrollToEdit, 50));
|
|
||||||
|
|
||||||
var scrollMap, lineHeightMap, viewTop, viewBottom;
|
var scrollMap, lineHeightMap, viewTop, viewBottom;
|
||||||
|
|
||||||
|
@ -291,19 +352,12 @@ function syncScrollToView(event, _lineNo) {
|
||||||
if (viewScrolling) return;
|
if (viewScrolling) return;
|
||||||
posTo = scrollMap[lineHeightMap[_lineNo]];
|
posTo = scrollMap[lineHeightMap[_lineNo]];
|
||||||
}
|
}
|
||||||
var posDiff = Math.abs(ui.area.view.scrollTop() - posTo);
|
ui.area.view.stop(true, true).scrollTop(posTo);
|
||||||
var duration = posDiff / 50;
|
preventViewScroll = true;
|
||||||
ui.area.view.stop(true, true).animate({
|
|
||||||
scrollTop: posTo
|
editScrolling = true;
|
||||||
}, duration >= 100 ? duration : 100, "linear");
|
clearTimeout(editScrollingTimer);
|
||||||
/*
|
editScrollingTimer = setTimeout(function () {
|
||||||
if (posDiff > scrollInfo.clientHeight / 5) {
|
editScrolling = false;
|
||||||
var duration = posDiff / 50;
|
}, editScrollingDelay);
|
||||||
ui.area.view.stop(true, true).animate({
|
|
||||||
scrollTop: posTo
|
|
||||||
}, duration >= 100 ? duration : 100, "linear");
|
|
||||||
} else {
|
|
||||||
ui.area.view.stop(true, true).scrollTop(posTo);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue