I’m very new to CM6 and probably missing some obvious pieces but please help me.
I want to scroll editor to a specific line with fractional precision. My use case is I’m showing a preview of the document being edited. I have a mapping between vertical positions in the preview and line numbers. I want to achieve smooth scrolling of the editor when the preview is scrolled.
I think I’ve found how to get line a number from editor position but I can’t find how to get a position from line number. I also found how to scroll a position into view but I believe it’s granularity is whole lines and it’s instantaneous without an option to animate it.
To get a line’s vertical position, you could use visualLineAtHeight. Smooth scrolling isn’t something the library will do for you—you’ll have to set up your own timed process that incrementally updates the scroll position of editor.scrollDOM.
Is it safe to rely on editor.scrollDOM position for the editor scroll position? Can I also put an event handler on it to monitor editor scroll position?
visualLineAtHeight seem to do the trick but it also seems a bit off.
Ah, I was looking at the wrong screenshot (where 3368 was in view). Anyway, if you don’t specify a 2nd argument, your first argument is interpreted in terms of window coordinates, so if the editor isn’t right at the top of the window, you’ll get the line that would sit there there, even if scrolled out of view.
Heights are interpreted relative to the given editorTop position.
My interpretation is that for each line editorTop has to increase. That is, for example, with lines of 20px, view.visualLineAtHeight(0, 10) would give me the first line view.visualLineAtHeight(0, 30) would give me the second and so on.
However, after experimentation I’ve found the following snippet that seem to give me the line number at the top edge of the editor:
I agree that is not very obvious. What is happening is that the height you pass is interpreted relative to some ‘top of the content’ value. If you don’t pass a second argument, it will use the pixel position of the top of the content on (or off) screen. That’s the usual case, used when interpreting something like mouseEvent.clientY. You can also pass 0 to have the first argument interpreted as a plain in-document vertical offset.
In your case, you’d want to pass view.scrollDOM.getBoundingClientRect().top as first argument, and omit the second argument. (What you’re doing now will work for most cases but break down when the content is so tall that non-rendered content is scaled down to avoid DOM size limitations.)
I’ve changed the argument name to docTop and modified the doc comments a bit in this patch to hopefully make this a bit more obvious.
contentDOM is what holds the lines, isn’t it? So with relation to it’s bounding rect I would always get the first line. I tried and it appears to be the case: regardless of the scroll position, I always get the first line.
Other options I tried is dom and scrollDOM. These two give me the topmost visible line. Which one is better to use?
And with regards of the documentation I wonder if it needs to be updated again or if I have done something not quite right again.
Recap:
I want the number of the topmost visible line in the editor. This code gives me it:
(For anyone following this thread, please note that visualLineAtHeight appears to be deprecated: Release 0.20.0. The new way to handle this is: CodeMirror Reference Manual)