memento of what you did

矩形云々をやると言いつつ、今度は undo/redo 周りに手を付けるライブ感覚。

レイヤーが3枚固定だった頃は、undo の仕組みはかなりシンプルで、リニアなリストに各レイヤー(を png でエンコードした data URL)を保持していた。それを undo マネージャが適宜使用するという memento パターンである。

さてレイヤーの枚数が自由になったので、リストの要素としてレイヤーそのものを直接持つのは容量的に良くなくなった。

そこで、undo リストとレイヤーのデータは管理を別にし、特に後者は版数と参照カウンタを伴ったクラスタとして保持するようにした。そのため undo リスト側では対応する版のレイヤーに対するポインタのみを保持することになる。

ところでひとつ気になるのは、前述の通りレイヤーをエンコードして保持している。これは容量削減のためなのだがエンコードに時間がかかるようだとよくない。ペンでクロスハッチを描く場合なんかは高速かつ大量に undo 情報の追加が行われる。ここで追加がもたつくのは避けたい。

なのでエンコードではなくcanvas要素そのものを保持することも考えられる。実はそのほうが undo 時に非同期的にデコードする処理を挟まなくていい分楽ではある。あるいはハイブリッドに、とりあえずクラスタ内のレイヤーはcanvasで持っといて、利用されないままある程度の時間が経過したら自動的にエンコードするとかにすればいいのかな。それがいいかもしれない。

* * *

data URL ではなく toBlob() で非同期的に blob に変換するようにした。これに伴い undo 情報の追加は数ミリ秒のオーダーになった。これならいいかな。

Leave a Reply

Your email address will not be published.