先日見つけたInteractというライブラリを使って簡単なサンプルを作ってみました。
灰色の場所をクリックすると矩形が追加されます。矩形はドラッグで移動させることと、端っこをつまむことでリサイズが可能です。
ポイント
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のページにあるサンプルを、ほぼそのまま書いています。
一応Fluxにのっとって書いてるのでComponentからActionCreatorsにいって、そこからDispatcherを経由してStoreが変更されて最終的にViewのレンダリングという流れになっています。ReactとInteractを組み合わせることで、非常に簡単に矩形のドラッグとリサイズに対応できました。しかもデータはクラスとして保存されてる状態なので、あとでAjaxとかでサーバーに送信するときも簡単にできていい感じです。