The approach that worked for me is to use Reflex to render the SVG. Reflex makes it fairly easy to visualize DOM objects on a web page and respond to mouse clicks on these objects. Using SVG (instead of canvas) allows you to access the rendered objects after the initial display, both for selection and editing (resizing, moving, changing colors, deleting).
Here are three start-up examples that use reflex / svg. Each of these includes a working demo (associated with the readme file).
Mark circles in places defined by the circle pack
Interactive knight tour animation.
3D spinning cube
Given that these examples are reflection-based, they are all written using the FRP coding style, but I tried to minimize the part of each of these programs that specifically uses FRP methods.
For example, a knight's tour and a spinning cube have a recursive code block containing only calls to view and update. In both cases, this block of code allows you to get feedback from viewing to the accumulation of state changes (update foldDyn)
From an example of a rotating cube:
rec view modelOrientation modelOrientation <- foldDyn update initialOrientation tick
From the example of a knight's tour:
rec startEvent <- view width height rowCount colCount board tour tour <- foldDyn (update board) [] $ leftmost [startEvent, advanceEvent]
The easiest way I started working with reflection is to clone the reflex-platform github repository and run the try-reflex script contained in this repository - just like the readme says for reflex-platform
An example of packing a circle requires a package of packing in a circle . An example of a rotating 3d cube requires a matrix packet . To enable the use of these packages, enable them in packages.nix in the reflex platform before running try-reflex - again, as indicated in the readme version of the reflex platform.