かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

React + TypeScript JSXでInteractを使う

先日見つけたInteractというライブラリを使って簡単なサンプルを作ってみました。

github.com

f:id:okazuki:20160108131128p:plain

灰色の場所をクリックすると矩形が追加されます。矩形はドラッグで移動させることと、端っこをつまむことでリサイズが可能です。

f:id:okazuki:20160108131334p:plain

ポイント

interactは、npmではinteract.jsという名前で配布されてます。tsdでとってきた型定義ではinteractという名前でexportされてるので、TypeScriptのコンパイルは通ってもJavaScriptをbrowserifyでコンパイルするときにこけてしまうので、TypeScriptの型定義ファイルの最後のほうにある部分を以下のように書き換える必要があります。

declare module "interact.js" {
    export = interact;
}

続けてReactとInteractの繋ぎの部分です。これはReactのComponentのcomponentDidMountでInteractのAPIを呼び出すことで実現します。以下のような感じです。

componentDidMount() {
    Interact(ReactDOM.findDOMNode(this) as HTMLElement)
        .draggable({
            inertia: true,
            restrict: {
                restriction: 'parent',
                endOnly: true,
                elementRect: { top: 1, left: 1, bottom: 1, right: 1 }
            },
            autoScroll: true,
            onmove: e => {
                CanvasActionCreators.move(
                    this.props.rectangle.id,
                    e.dx,
                    e.dy);
            }
        })
        .resizable({
            preserveAspectRatio: false,
            edges: { left: true, right: true, bottom: true, top: true },
            onmove: e => {
                CanvasActionCreators.resize(
                    this.props.rectangle.id,
                    e.deltaRect.left,
                    e.deltaRect.top,
                    e.rect.width,
                    e.rect.height);
            }
        });
}

ReactDOMのfindDOMNodeでDOMをとってきて、Interactに食わせています。そのあとに続く処理の内容はInteractのページにあるサンプルを、ほぼそのまま書いています。

interactjs.io

一応Fluxにのっとって書いてるのでComponentからActionCreatorsにいって、そこからDispatcherを経由してStoreが変更されて最終的にViewのレンダリングという流れになっています。ReactとInteractを組み合わせることで、非常に簡単に矩形のドラッグとリサイズに対応できました。しかもデータはクラスとして保存されてる状態なので、あとでAjaxとかでサーバーに送信するときも簡単にできていい感じです。