suren-atoyan / monaco-react

Monaco Editor for React - use the monaco-editor in any React application without needing to use webpack (or rollup/parcel/etc) configuration files / plugins
https://monaco-react.surenatoyan.com/
MIT License
3.82k stars 269 forks source link

How to implement sync scroll preview? #604

Open agusmakmun opened 8 months ago

agusmakmun commented 8 months ago

I'm trying to implement the sync scroll for markdown preview such as https://markdownlivepreview.com So, the goal is "when the editor scrolling down or up, then the preview will follow".

and referring to this initScrollBarSync https://github.com/tanabe/markdown-live-preview/blob/main/public/js/main.js#L143 but still not luck.

How do we implement it using this react monaco editor?

Here is my below snippets:

<MonacoEditor
  height="100%"
  defaultLanguage="markdown"
  theme="vs-dark"
  options={{
    minimap: {
      enabled: false,
    },
    wordWrap: 'on',
    automaticLayout: true,
  }}
  onChange={onCodeChange}
  onMount={handleEditorDidMount}
/>

Then in handleEditorDidMount:

function handleEditorDidMount(editor: any, monaco: any) {
  console.log('onMount: the editor instance:', editor);
  console.log('onMount: the monaco instance:', monaco);

  editor.onDidScrollChange((scrollData: any) => {
    console.log('scroll', scrollData);

    // const editorElement = editor.getDomNode();
    // const previewElement = document.querySelector('#markdown-content') as HTMLElement;

    // const editorHeight = editorElement.scrollHeight - editorElement.offsetHeight;
    // const previewHeight = previewElement.scrollHeight - previewElement.offsetHeight;

    // if (editorHeight === 0) return; // Avoid division by zero

    // const ratio = editor.getScrollTop() / editorHeight;
    // const targetY = previewHeight * ratio;

    // console.log('editor.getScrollTop()', editor.getScrollTop());
    // console.log('ratio', ratio);
    // console.log('targetY', targetY);
    // previewElement.scrollTop = targetY;

    let editorElement = editor.getDomNode();
    let ratio = editorElement.scrollTop / (editorElement.scrollHeight - editorElement.clientHeight);

    console.log('editorElement.scrollTop', editorElement.scrollTop)
    console.log('editorElement.scrollHeight', editorElement.scrollHeight)
    console.log('editorElement.clientHeight', editorElement.clientHeight)
    console.log('ratio', ratio)

    let previewElement = document.querySelector('#markdown-content') as HTMLElement;
    let targetY = (previewElement.scrollHeight - previewElement.clientHeight) * ratio;

    console.log('targetY', targetY)
    previewElement.scrollTo(0, targetY);
  });
}