ReactとCanvasで画像のリサイズや回転を行う

Canvasを学ぶ必要があり、その練習として作ってみた。

ただの習作だから別に公開する必要はないのだが、いろいろあり、仕事以外でもコードを書いて公開していこうと思うようになった。
そのほうがちゃんと続けられるだろうし。
職場では他のホスティングサービスを使っているから、GitHubの使い方に慣れておきたい、というのもある。だから自分でレビューコメントを書いたりIssueを立てたりしている。

感想

昔に比べれば、スムーズにプログラムを書けるようになった感じはする。あくまでも過去の自分に比べれば、だけど。

Canvasについて理解が深まったとは言い難いが、まあ、最初の一歩にはなった。

アップロードした画像をクリックすることで画像を回転させられるのだが、これは、公開されているライブラリに頼った。自力でやりたかったのだが、JavaScriptExifを扱う方法がよく分からなかった。
ここらへんはもっと勉強したい分野なので、ライブラリに頼らず自力で出来るようになりたい。まずはライブラリの中身を読むことからだろうか。シンプルなライブラリだし。

今後

他にも追加したい機能があるので、チマチマとやっていきたい。
せっかくだからテストやFlowも書く。

フロントエンドでの画像処理について、もっと勉強したい。
Canvasを勉強したい理由も、それを使ってリッチなUXを提供したいとか、アニメーションをやりたいとか、そういうことではなく、それがフロントエンドで画像を扱う際の手段として有用だから。
Exifとか以前に、DataURLとかBlobとか全然分かってないから、そういうことも勉強する必要がある。

参考にした記事

定数に対してFlowの型を設定する

定数に対してFlowの型を設定する場合、工夫というか、トリッキーな書き方をしないと上手く動かない。
業務で必要になり調べ、GitHubのIssueで解決策を見つけたのだが、日本語の資料や記事は見当たらなかった。
ちょっとした小ネタだが、誰かの役に立つかもしれないし、自分の備忘録も兼ねて書いておく。

Flowのバージョンは0.46.0で、動作確認をしている。

まず、何も考えず普通に書いてみる。

// @flow

const NORMAL_MEMBER_CODE = 'qwerty';
const ADMIN_CODE = 'admin';

type Code = NORMAL_MEMBER_CODE | ADMIN_CODE;

function sendCode(code: Code): void {
  // 何らかの処理
  console.log(code);
}

sendCode('admin');

最初に、NORMAL_MEMBER_CODEADMIN_CODEという2つの定数を定義している。
sendCodeの引数は必ずCodeという型であり、これは、NORMAL_MEMBER_CODEADMIN_CODEのいずれかである。 何もおかしなところはない。

しかしこれをFlowでチェックすると、エラーになる。

6: type Code = NORMAL_MEMBER_CODE | ADMIN_CODE;
               ^^^^^^^^^^^^^^^^^^ string. Ineligible value used in/as type annotation (did you forget 'typeof'?)
6: type Code = NORMAL_MEMBER_CODE | ADMIN_CODE;
               ^^^^^^^^^^^^^^^^^^ NORMAL_MEMBER_CODE


6: type Code = NORMAL_MEMBER_CODE | ADMIN_CODE;
                                    ^^^^^^^^^^ string. Ineligible value used in/as type annotation (did you forget 'typeof'?)
6: type Code = NORMAL_MEMBER_CODE | ADMIN_CODE;
                                    ^^^^^^^^^^ ADMIN_CODE

(did you forget 'typeof'?)と出ているので、Codeの定義を以下のように書き換えてみる。

type Code = typeof NORMAL_MEMBER_CODE | typeof ADMIN_CODE;

これなら確かに、エラーは出ないようになる。
しかしこれは、Codestringですと定義しているだけであり、文字列なら何でも通ってしまう。
例えばsendCode('hoge');でも、Flowはエラーを出さない。
qwertyadmin以外ではエラーを出すのが、意図する挙動である。

正解は、以下。

// @flow

const NORMAL_MEMBER_CODE: 'qwerty' = 'qwerty';
const ADMIN_CODE: 'admin' = 'admin';

type Code = typeof NORMAL_MEMBER_CODE | typeof ADMIN_CODE;

function sendCode(code: Code): void {
  // 何らかの処理
  console.log(code);
}

// sendCode('hoge'); // Found 1 error
sendCode('admin'); // No errors!

これで、正しく動くようになり、qwertyadmin以外ではエラーを出すようになった。

参考資料