I often write SVGs by hand for my pages instead of using a GUI tool like Inkscape. If I want to tweak something, I’ll change a number in the text editor, then reload the page. I decided I could improve that process by making the numbers editable on the page itself. I used CodeMirror with the codemirror-interact extension[1] , which lets you alt-drag numbers to change them (scrubbing interface):
I put this into my /mjs folder, and then I can use it:
<script type="module"> import {attachEditorToElement} from "/mjs/scrubbable-codemirror.js"; for (let el of document.querySelectorAll("svg")) attachEditorToElement(el); </script>
I made this a bookmarklet so that I could use it on any of my pages:
javascript:(async function(){const {attachEditorToElement} = await import ("https://www.redblobgames.com/mjs/scrubbable-codemirror.js");for (let el of document.querySelectorAll("svg")) attachEditorToElement(el)})()
If you’re wondering why not Inkscape, it’s because my SVGs are tied to the structure and styling of the page, including some parts of them edited by Javascript, and some parts of them relying on the CSS. Inkscape is fine for standalone SVGs but that’s not what I’m making.
Not yet implemented: using to edit the template instead of the output SVG, so that I can wire up all of my interactivity to the editor.
1 Implementation#
I started by setting up CodeMirror using https://codemirror.net/examples/basic/[2] and https://codemirror.net/docs/guide/[3]. It took some time to figure out how to connect the parts to make a minimal working example where I could read the text out, not just initialize it.
pnpm install @codemirror/state @codemirror/view @codemirror/commands @codemirror/language @codemirror/lang-xml @replit/codemirror-interact
Once I had CodeMirror working, I added the ingredients step by step:
- Add syntax highlighting.
- Add the scrubble number extension.
- Read the initial value from the
outerHTMLof an element - Write any changes back to the
outerHTMLof the element. This was a little tricky because writing to theouterHTMLinvalidates the previous references to that element.
Source: scrubbable-codemirror.js