Regroup2019の技術まとめ
a (T1 | null)
a! (T1)
create-react-app
$ npx create-react-app <my-app> --typescript
アプリのテンプレートを作ってくれるので素直に従ってる
Webpack:
$ npm start
ローカルで開発サーバが立ち上がる
ソースを編集すると自動でビルドする
ブラウザのオートリロードもついてくるので便利
やってないけどHTTPSでサーブ設定にもできるので製品のJSカスタマイズ開発にも楽チン
$ npm build
React
特にこだわりはない
DOMベースのアプリだと部品の再利用に良いのかも
Regroupは大きなHTMLCanvasElememtがドカンとあるアプリなのであまり活用されてなさげ
balloonMenu
サードパーティのコンポーネントを使うと便利かも
モーダルダイアログとか
状態の更新によってビューの再描画がかかる仕組み
DOMを直接操作しない思想
やっぱりうまくいかないケースはある
HTMLCanvasElememtでパスドローする 書いた線を滑らかにするのはこれに丸投げ
線がガタガタになるのは嫌いなのでこの機能がiPadでスムーズに使えるのがこれを使う決め手になった
strokeCap = "round"
lineJoin = "round"
投げ縄選択はパスのブーリアン演算で実現してる
サーバ上の値が変わるとリスナーが呼ばれるのでちょっとした情報共有的アプリのプロトタイプ作りに楽チン
オフラインでもローカルに溜めて、オンラインになった時に保存してくれる
しかしブラウザをリロードしたりしたら失われるし共同編集時のコンフリクトの解決などはしないので安心しきってはいけない
ホスティング
npm i -g netlify-cli して netlify deploy -d public --prod で指定したディレクトリを netlify にアップロード
デプロイした静的サイトは CDN 上に展開される
ビルド毎にハッシュ付きの URL が生成され、デプロイ ID がわかっていれば、その時点のものにアクセスできます。
Firebase Function のような FaaS もついています。中身は AWS Lambda
Apple pencilに慣れてる僕にとっては区別する方が自然だが、慣れてないユーザの振る舞いを見てると、ちょっと習得コストを支払う必要がありそう
スムーズな拡大縮小
机と付箋でやってるKJ法をデジタル化することを目指していたのでiPad上で200枚程度の付箋を出した状態でスムーズに拡大縮小、移動ができることが必要
二本指ジェスチャーの開始時点でCanvasの内容をHTMLImageElememtにして、JSではなくブラウザ自身のレンダリングに任せた
React的状態管理
状態の更新によってビューの再描画がかかる仕組み
状態オブジェクトを破壊的に更新してはいけない
状態の変化を内容ではなく同一性で判定しているため
描画対象の親子関係をツリーで表現するのと相性が悪い
破壊的更新ができないので子が更新されたら祖先もすべて更新する必要がある
そう実装した
それで良いのか?
Reactの関数コンポーネントのReact的状態は関数スコープ
子コンポーネントには更新関数を引数に渡す
マウスイベントのハンドラの中で更新したいのでそこまで渡す必要があるが面倒
この状態の扱いに少し戸惑ってあまり良くない設計になってしまった
UNDOの実装
必須の機能だと考えている
単にすべてのスナップショット履歴を保持してる
パフォーマンスに問題が出たら考えよう、という状態
Reactの状態更新とUNDOの単位が同一だったが、これは良くない
人間にとって自然なUNDOの粒度は状態更新の基本単位とは異なる
例えば複数オブジェクトを選択して移動した場合:
状態更新の自然な実装としては「1つのオブジェクトの位置更新」を選択されたオブジェクトに対して実行
この更新単位をUNDOの単位にすると「オブジェクトが1個、元の位置に戻る」
これは人間にとって自然ではない
画像の扱い
他のサーバにある画像を表示することはできる
レスポンスヘッダによってはその後書き出しが不可能になる(セキュリティ上の制約)
画像点滅問題
ChromeとSafari(やiPadのChrome)に挙動の差がある
画像を貼ったマップをその後編集した時の再描画で、Safariではローカルの画像を破棄してネットから取得してしまう
結果、すべての画像付箋が移動のたびに点滅する
これはレスポンスヘッダでしっかりキャッシュさせることで抑制できる
プロキシサーバを作って両方の問題を解決
画面サイズ
ズーム
マウスイベント
Paper.jsにはToolの切り替えの仕組みがある
マウスイベントを受け取るオブジェクトが切り替わる
これを使って移動モード、ペンモード、投げ縄選択モードを切り替えている
しかしペンモードでも移動したいよな…
整理した方が良さそう
DOMで浮かべる