Regroup2019の技術まとめ
2019年に作ったRegroupの要素技術をまとめる: pRegroup-done-2019
cf. 2020 年、 React 軸で学ぶべき技術
TypeScript+React+Webpack
TypeScript: Visual Studio Codeで型情報を使って補完やミスの検出がされるので生のJavaScriptより圧倒的に良い
TypeScript再入門「がんばらないTypeScript」で、JavaScriptを“柔らかい”静的型付き言語に(gfx執筆) - エンジニアHub|若手Webエンジニアのキャリアを考える!
a (T1 | null)
a! (T1)
create-react-app
$ npx create-react-app <my-app> --typescript
アプリのテンプレートを作ってくれるので素直に従ってる
https://github.com/facebook/create-react-app
Webpack:
$ npm start
https://webpack.js.org/configuration/dev-server/
ローカルで開発サーバが立ち上がる
DevServer | webpack
ソースを編集すると自動でビルドする
ブラウザのオートリロードもついてくるので便利
やってないけどHTTPSでサーブ設定にもできるので製品のJSカスタマイズ開発にも楽チン
$ npm build
React
特にこだわりはない
DOMベースのアプリだと部品の再利用に良いのかも
Regroupは大きなHTMLCanvasElememtがドカンとあるアプリなのであまり活用されてなさげ
balloonMenu
Regroupでは使ってないが別アプリでstyled-componentsを使って、割と良かった
サードパーティのコンポーネントを使うと便利かも
モーダルダイアログとか
ReactModal
状態の更新によってビューの再描画がかかる仕組み
DOMを直接操作しない思想
やっぱりうまくいかないケースはある
iPadはfocusを無視することがある
paper.js
HTMLCanvasElememtでパスドローする
書いた線を滑らかにするのはこれに丸投げ
線がガタガタになるのは嫌いなのでこの機能がiPadでスムーズに使えるのがこれを使う決め手になった
パスの形がおかしい問題
strokeCap = "round"
lineJoin = "round"
投げ縄選択はパスのブーリアン演算で実現してる
付箋・パスの投げ縄選択
Firestore
ドキュメント指向 DB + Websocket 経由の Subscription
サーバ上の値が変わるとリスナーが呼ばれるのでちょっとした情報共有的アプリのプロトタイプ作りに楽チン
オフラインでもローカルに溜めて、オンラインになった時に保存してくれる
しかしブラウザをリロードしたりしたら失われるし共同編集時のコンフリクトの解決などはしないので安心しきってはいけない
ホスティング
静的ホスティングだけだったのでAmazon S3に突っ込んでHTTPでサーブしてる
後から知ったNetlifyとか使うと良さそう
npm i -g netlify-cli して netlify deploy -d public --prod で指定したディレクトリを netlify にアップロード
デプロイした静的サイトは CDN 上に展開される
ビルド毎にハッシュ付きの URL が生成され、デプロイ ID がわかっていれば、その時点のものにアクセスできます。
Firebase Function のような FaaS もついています。中身は AWS Lambda
2020 年、 React 軸で学ぶべき技術 - mizchi's blog
Apple pencil
タッチと区別できる: iPad上でのダイレクトタッチとPencilタッチの区別
Apple pencilに慣れてる僕にとっては区別する方が自然だが、慣れてないユーザの振る舞いを見てると、ちょっと習得コストを支払う必要がありそう
スムーズな拡大縮小
机と付箋でやってるKJ法をデジタル化することを目指していたのでiPad上で200枚程度の付箋を出した状態でスムーズに拡大縮小、移動ができることが必要
二本指ジェスチャーの開始時点でCanvasの内容をHTMLImageElememtにして、JSではなくブラウザ自身のレンダリングに任せた
関連: 二本指ジェスチャでズームと平行移動
React的状態管理
状態の更新によってビューの再描画がかかる仕組み
状態オブジェクトを破壊的に更新してはいけない
状態の変化を内容ではなく同一性で判定しているため
描画対象の親子関係をツリーで表現するのと相性が悪い
破壊的更新ができないので子が更新されたら祖先もすべて更新する必要がある
そう実装した
それで良いのか?
Reactの関数コンポーネントのReact的状態は関数スコープ
子コンポーネントには更新関数を引数に渡す
マウスイベントのハンドラの中で更新したいのでそこまで渡す必要があるが面倒
この状態の扱いに少し戸惑ってあまり良くない設計になってしまった
Reduxに移行するかな?と考えてたがreactnが良さそう
Context – Reactの仕組みを使いやすくラップしたもの
UNDOの実装
必須の機能だと考えている
単にすべてのスナップショット履歴を保持してる
パフォーマンスに問題が出たら考えよう、という状態
undoの実装
Reactの状態更新とUNDOの単位が同一だったが、これは良くない
人間にとって自然なUNDOの粒度は状態更新の基本単位とは異なる
例えば複数オブジェクトを選択して移動した場合:
状態更新の自然な実装としては「1つのオブジェクトの位置更新」を選択されたオブジェクトに対して実行
この更新単位をUNDOの単位にすると「オブジェクトが1個、元の位置に戻る」
これは人間にとって自然ではない
画像の扱い
キャンバス汚染問題
他のサーバにある画像を表示することはできる
レスポンスヘッダによってはその後書き出しが不可能になる(セキュリティ上の制約)
画像点滅問題
ChromeとSafari(やiPadのChrome)に挙動の差がある
画像を貼ったマップをその後編集した時の再描画で、Safariではローカルの画像を破棄してネットから取得してしまう
結果、すべての画像付箋が移動のたびに点滅する
これはレスポンスヘッダでしっかりキャッシュさせることで抑制できる
キャンバス汚染解決編
プロキシサーバを作って両方の問題を解決
画面サイズ
CSSで条件分岐と変数と計算を使う
100vhだと縦にはみ出す
メニューアイコンがiPhoneなどの狭い画面ではみ出す
ズーム
ズームアウトした状態でペンで描くとガタガタになる
線の太さを一定にする
Paper.jsの更新後に呼ばれるコールバックをつける
マウスイベント
Paper.jsにはToolの切り替えの仕組みがある
マウスイベントを受け取るオブジェクトが切り替わる
これを使って移動モード、ペンモード、投げ縄選択モードを切り替えている
しかしペンモードでも移動したいよな…
整理した方が良さそう
バルーンメニュー
DOMで浮かべる
投げ縄選択→削除
付箋の自動フォントサイズ調整
gが下に突き出す
OKR問題
Regroup2019