viliusle / miniPaint

online image editor
http://viliusle.github.io/miniPaint/
Other
2.62k stars 610 forks source link

Save and load including history #239

Closed flange-ipb closed 2 years ago

flange-ipb commented 3 years ago

Hi, would it be possible to save and load the image data and the edit history, probably via a JSON object?

Use case: Upon sending a HTML form via AJAX, the web framework I use updates the whole form (including miniPaint embedded via an iframe). This also happens if validation errors exist (the framework needs to render some messages), but in this case the data doesn't reach the backend and the database. The miniPaint instance thus restarts with a new blank image and I'd like to return to its previous state. I guess I could serialize the state via localStorage (like it's done in quicksave()), sessionStorage or just store it in a JS variable (no page reload happens).

Thanks, Frank

Giwayume commented 3 years ago

The undo history isn't very serializable. Object instances of these classes are stored in memory and you'd especially have a tough time with update-layer-image.js which commits entire images to IndexedDB instead of storing them in memory.

I'd suggest an easier solution would be to yank the miniPaint iframe out of the form before you submit it, then place it back inside after it's re-rendered so you don't lose it.

flange-ipb commented 3 years ago

OK, my first thought was to serialize the miniPaint.State.action_history array, but there are a lot of object references that cannot be reconstructed properly during deserialization.

Your suggestion to move the iframe within the DOM tree is fantastic, but it seems iframe elements are always reloaded when appending them as child, thus the editor state is lost. The next thing I will try is to include the markup from index.html directly.

Giwayume commented 3 years ago

Oh wow, all these years I never knew that you can't move iframes without reloading. The CSS isn't designed to be included on other pages, pretty sure it tries to take over the whole page.

I'm not sure of your exact scenario, but can you rework your form to have a button that opens MiniPaint in a modal instead? Or is MiniPaint showing inline on the page important to the functionality of the form?

Like this: https://jsfiddle.net/z3vud46g/