I’m working in Elm on kind of a game, and what I need to achieve is this:
user can create new HTML elements (e.g. divs) on the page
user can drag & drop the elements
user can resize the elements
user can save the page state to the server and load it back (so the whole HTML page will be loaded from the server and restored)
I have problem with the resizing. I can use the CSS ‘resize: both’ style, but I can’t read the element’s new size, and so I couldn’t save it then to and restore from the server. For dragging there are HTML events (and also there are Elm libraries), but for resizing there are no events, and so I can’t use same approach.
Is there any way/idea/workaround to keep tracking changing element’s size when user freely resizes it?
Another possible option I think of is to read all the DOM, iterate through every element, read its properties (like size, position, etc.), and save it so then it all could be restored. Is there any way to do this in Elm? Let’s say, all the actions happen inside a ‘container’ DIV that is created in the Elm application, and all elements user creates are created as children of the container - is there any way in Elm to iterate all the child elements of the container DIV?
Rather than using ports I would wrap the observer in a custom element and have it fire events, port wiring is cumbersome compared to regular events IMO.
You could do this with just Elm, no ports. I made a table with resizeable columns this way.
Place a div on each edge of the elements, with onMouseDown (MouseDown itemId <Edge>)
type Edge = Top | Bottom | Left | Right
subscriptions = Browser.Events.onMouseMove <|
Decode.map2 MouseMove
(Decode.field "pageX" Decode.int)
(Decode.field "pageY" Decode.int)
update msg model
case msg of
MouseDown id edge ->
({model | dragging = Just (id, edge)}, Cmd.none)
MouseMove x y ->
case model.dragging of
Just (id, edge) ->
-- do some math and update the dragged item's height/width/position etc.
Nothing ->
(model, Cmd.none)
Sorry for the brief example, hope it makes sense
Btw, the css resize property is not supported by IE or Edge, but doing it this way works.