1

I have a question about Elm canvas. Is there a way to prevent the canvas to be erased/reinserted in the DOM on each frame?

I am trying to dynamically generate an image by changing a particle system (Model) and then drawing it. The pseudocode looks like bellow.

My only "solution" is not to change the particles and instead to keep adding but I am not happy with the approach.

type alias Particle = { ... }

type alias Model = List Particle 

update msg model =
  List.map updateParticle model

view model = 
  collage 900 900
    ((rect 900 900 |> filled bg) :: (List.map drawParticle model))


-- later edit
drawParticle p =
  segment p.start p.end
  |> traced defaultLine

[EDIT] In order to make it clear what the DOM contains, I added drawParticle function to the code above.

Adrian
  • 1,006
  • 2
  • 9
  • 20

1 Answers1

0

I've been asked in the comments to answer my own question. Although this is not the answer to my question but an workaround, and a not very efficient one.

type alias Particle = { ... }

type alias Model = { particles : List Particle, lines : List Form } 

update msg model =
  let 
    newParts = List.map updateParticle model.particles
    newLines = List.map particleToLine newParts
  in 
    Model newParts (model.lines ++ newLines)


view model = 
  collage 900 900
    ((rect 900 900 |> filled bg) :: model.lines)

What changed? First, Model now keep a lines list to be drawn. update function produce a new set of lines every step and append it to the ones already generated. view function is not rendering the particles anymore but just add the lines to the collage.

Performance wise, this is a terrible "solution" as the number of lines in the model continually increase with every AnimationFrame.

A better approach would be to save the image data of the canvas after every render and use it a background for next render. But I have no idea how to do this.

Hope this helps.

Adrian
  • 1,006
  • 2
  • 9
  • 20