From df41b584410d1368fa28f1bd1d65e233100b29ca Mon Sep 17 00:00:00 2001 From: Trevor Buckner Date: Fri, 3 Jun 2022 13:32:04 -0400 Subject: [PATCH] Smooth scroll editor Panel, and flash target line --- client/homebrew/editor/editor.jsx | 31 ++++++++++++++----- shared/naturalcrit/codeEditor/codeEditor.less | 11 +++++-- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 77c520431..77c655163 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -19,8 +19,6 @@ const DEFAULT_STYLE_TEXT = dedent` color: black; }`; -const sourceMoveHighlightClass = 'sourceMoveFlash'; - const splice = function(str, index, inject){ return str.slice(0, index) + inject + str.slice(index); }; @@ -133,7 +131,7 @@ const Editor = createClass({ //reset custom line styles codeMirror.removeLineClass(lineNumber, 'background', 'pageLine'); codeMirror.removeLineClass(lineNumber, 'text'); - codeMirror.removeLineClass(lineNumber, 'wrap', sourceMoveHighlightClass); + codeMirror.removeLineClass(lineNumber, 'wrap', 'sourceMoveFlash'); // Styling for \page breaks if((this.props.renderer == 'legacy' && line.includes('\\page')) || @@ -217,12 +215,29 @@ const Editor = createClass({ const textPosition = textString.length; const lineCount = textString.match('\n') ? textString.slice(0, textPosition).split('\n').length : 0; - targetLine = lineCount; - } + targetLine = lineCount - 1; //Scroll to `\page`, which is one line back. - // this.refs.codeEditor.codeMirror.scrollIntoView({ line: targetLine, ch: 0 }, 30); - this.refs.codeEditor.setCursorPosition({ line: targetLine, ch: 0 }); - this.refs.codeEditor.codeMirror.addLineClass(targetLine, 'wrap', sourceMoveHighlightClass); + let currentY = this.refs.codeEditor.codeMirror.getScrollInfo().top; + let targetY = this.refs.codeEditor.codeMirror.heightAtLine(targetLine, 'local', true); + + //Scroll 1/10 of the way every 10ms until 1px off. + const incrementalScroll = setInterval(()=>{ + currentY += (targetY - currentY) / 10; + this.refs.codeEditor.codeMirror.scrollTo(null, currentY); + + // Update target: target height is not accurate until within +-10 lines of the visible window + if(Math.abs(targetY - currentY > 100)) + targetY = this.refs.codeEditor.codeMirror.heightAtLine(targetLine, 'local', true); + + // End when close enough + if(Math.abs(targetY - currentY) < 1) { + this.refs.codeEditor.codeMirror.scrollTo(null, targetY); // Scroll any remaining difference + this.refs.codeEditor.setCursorPosition({ line: targetLine + 1, ch: 0 }); + this.refs.codeEditor.codeMirror.addLineClass(targetLine + 1, 'wrap', 'sourceMoveFlash'); + clearInterval(incrementalScroll); + } + }, 10); + } } }, diff --git a/shared/naturalcrit/codeEditor/codeEditor.less b/shared/naturalcrit/codeEditor/codeEditor.less index 53be7e5f5..c929e0d21 100644 --- a/shared/naturalcrit/codeEditor/codeEditor.less +++ b/shared/naturalcrit/codeEditor/codeEditor.less @@ -3,6 +3,11 @@ @import (less) 'codemirror/addon/search/matchesonscrollbar.css'; @import (less) 'codemirror/addon/dialog/dialog.css'; +@keyframes sourceMoveAnimation { + 50% {background-color: red; color: white;} + 100% {background-color: unset; color: unset;} +} + .codeEditor{ .CodeMirror-foldmarker { font-family: inherit; @@ -11,8 +16,8 @@ } .sourceMoveFlash .CodeMirror-line{ - background-color: #0000fc; - color: #ffffff; + animation-name: sourceMoveAnimation; + animation-duration: 0.4s; } //.cm-tab { @@ -24,4 +29,4 @@ // background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAQAgMAAABW5NbuAAAACVBMVEVHcEwAAAAAAAAWawmTAAAAA3RSTlMAPBJ6PMxpAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAFUlEQVQI12NgwACcCQysASAEZGAAACMuAX06aCQUAAAAAElFTkSuQmCC) no-repeat right; // } //} -} \ No newline at end of file +}