from pRegroup2020

2019-07-16

  • Reconsilerを差し替えてiPadでの画像点滅が止まるか検証 done

  • テキストのない付箋が表示されるところまでどうにか進んだ

    • テキストのない付箋が表示されるようになった
    • テキスト部分はコメントアウトしている
    • パスは今コメントアウトしている
    • グループも今コメントアウトしている
  • canvasのresizeイベントもコメントアウトされて固定サイズになっている

  • ここら辺を順次戻して行って表示が元どおりになるようにする

  • それからまずは平行移動とズーム、次に付箋のドラッグでの移動を動かす

2019-08-02

  • テキストの表示done
  • base canvasとoverlay canvasがそれぞれPaperScopeを持っている
  • basePaperとoverlayPaperって名前にした
  • app.paperを削除
    • 色々なところで使いまくっている
    • Toolもapp.paperにぶら下がっている
      • 一旦コメントアウト
    • 拡大縮小できるようになった(拡大縮小完了時に状態をセットしようとして死ぬ)
    • 状態を更新する必要はないのではないかと考えてコメントアウト
  • ズームはできるようになった
  • 平行移動を実現
  • manualを開いて見られるようにする commit id: f182638

pRegroupに書き連ねられたものの集合体:


状態管理の刷新について理解の整理

  • 本質的にこのアプリは「HTML5のCanvasにレンダリングするアプリ」である

  • 直接Canvasに描画するのではなくPaper.jsを使っている(当たり判定などの丸投げのため)

  • React的状態が更新されたらPaper#Itemを全破棄して再生成している

  • その実装でPCのChrome上では問題なく動く

  • iPadのSafari、Chrome、PCのSafariでは付箋の枚数によらず「画像の貼られた付箋」に不愉快な点滅が発生する

  • おそらくPCのChromeだけ、Paper.jsより下のレイヤ(=ブラウザ)で画像のキャッシュをしている

  • iPadで快適に動くためには、Paper#itemが破棄されないようになる必要がある

  • それはつまり、React的状態が更新された時に、Paper.jsのレイヤーでは既存のオブジェクトの修正や移動で対処する必要がある

  • これはReactがDOMに対して行なっているのとほぼ同等の処理、それを担当するのはReconciler

  • 自分でReconcilerを実装するか、既存の実装を利用する必要がある。実装したくないのでreact-paper-bindingsを使う

  • オブジェクトに一意なIDをつける

  • 加えて、現状全体のstateがUNDO対象になっているが、UNDOは必要に応じてスナップショットをpushしていく形に変える


  • 状態の代わりに関してはまずは一意なIDを持つようにしてreactがリストのレンダリングに使っているのと同じ仕組みでできないか試すべきだな、自前で差分レンダリングを作るのはなるべく避けたい

  • だけども最終的に出力されるものがpaper.jsの要素のリストだからDOM操作のメソッドは使えないので、そこをどうするのか

  • react-paper-bindingがどういう実装をしているか観察

  • オブジェクトが一意なIDを持つ必要がある、という点はReactの言葉ではKeyと言うらしい

    • https://reactjs.org/docs/reconciliation.html
    • で子要素を持つようなコンポーネントに更新があった場合には、ReconcilerがそのKeyをみて子要素を新しく作るのか破壊的に更新するのかを決める感じか
  • https://github.com/nitin42/Making-a-custom-React-renderer/blob/master/part-one.md

  • react-paper-bindingを使うので良さそう

    • https://github.com/psychobolt/react-paperjs
    • とどちらが良いかと言うことに関しては判断がつかない
    • こちらの方が最終更新は新しい
    • react-paper-bindingの方がコントリビュータは多いなぁ

状態管理

  • iPad上での画像付箋の描画が遅れる問題

    • 設計の深いところに手を入れれば「画像付箋を100枚出してもちらつかない」って理想は実現できると思うが

      • 「UNDOの機能を維持したまま」だとこれ、そう簡単ではないな。
      • かといってUNDOの機能を捨てるのはちょっとなぁ…
  • 問題の整理

    • Reactの状態管理と辻褄の合うUNDO/REDOの仕組みを調べた時に、参考にした2つの実装が両方とも「状態が更新されたら全部再描画」になっていて当時僕は「そんなのでいいのか?性能上の問題が出るのでは?修正差分で管理する形にするべきでは?」って考えてから
    • 若干モヤモヤするけど早すぎる最適化は諸悪の根源なので「全状態履歴を保持する実装」でまずは作る。

    • という判断をしたわけだ。でもって、100枚付箋を出して動かしたりしても意外と性能上の問題が出なかった。
    • で、ここまで来て「iPad上で画像の付箋を100枚出す」という条件でついに問題が出たわけだ。
  • 画像が1枚でも「iPad上では画像が0.5〜1秒遅れて描画される」って振る舞いなのでこの問題を解決するには極力描画済みのオブジェクトを使い回すような実装にしなきゃいけない

  • Paper.jsのオブジェクトのツリーをReactの仮想DOMみたいに扱う必要があるのか

  • 共同編集できるようにしたい

    • 一人でも共同編集は必要
    • 付箋の移動はやはりiPadで指でひょいひょい動かしたい
    • 付箋の追加に関しては、キーボードが使いたいからPCでやりたい
    • 編集モードで2箇所で開いたせいで、片方の編集で片方を上書きしてしまうミスをしたw
    • やっぱり、一人で使うとしても共同編集はできるべきなのです(結論)
    • 今共同編集がOFFにされている理由は「片方の編集者がドラッグなどしている最中に、他の編集者の編集が到着してオブジェクトが再生成された場合に、ドラッグ完了時にドラッグ対象のオブジェクトを見つけられなくて死ぬ」ということなので結局やっぱりPaper#ItemがReact上の状態オブジェクト(StateItem)への参照を持っている状態がダメで全てのStateItemにuniqueなIDをつけて、ドラッグ完了のタイミングでシーンツリーからそのIDのオブジェクトを検索してそれを更新するって仕組みにするべき