【ドット絵エディタ制作】11回目:お絵かきエリアの追加とコピペ

お絵かきエリアを2つに増やし、描画内容をコピペできるようにした。

作ったもの

選択範囲ツールで選択した内容をコピペもしくはカットペできる。
2つのお絵かきエリアを横断してコピペ・カットペも可能。

なお、前回まであったドラッグツールは、コピペ・カットペツールで代用できるので、削除した。

確認用ページ

ソースコード

クラス図

クラス図での変更点はDragLayerの名称をTemporaryLayerに変更したのみで
新たなクラスは追加していない。

クラス図からはわからないが
お絵描きエリアが2つになったのでWorkspaceのインスタンスも2つに増えた。

なお、レイヤークラスの名称を変更したため、
Workspace内のレイヤー構造の概略図を更新しておく。

つまづきポイント

コピペの処理の流れ(カットペもほぼ同じ)

ポイントは②で両方のWorkspaceのTemporaryLayerに描画内容を複製しておくこと。
一見、無駄な処理のようにも見えるが、
こうしておくことで、ユーザーがどちらのWorkspaceを操作しても
TemporaryLayerの表示・非表示を切り替えるだけで済むので、楽。

createjsのStageにおけるmouseoverとrolloverの違い

mouseoverイベントは描画領域に対して反応するのに対し、
rolloverイベントはStageに対して反応する。

また、mouseoverイベントのイベントハンドラにおけるevent.taretは
StageではなくShapeやSpriteなどの描画オブジェクト。

TemporaryLayerの座標計算ミス

以前から、コピペやカットペの最後の処理で
TemporaryLayerからDrawLayerに描画データを移す際に
座標がずれてしまう問題があった。

これまでは、その場しのぎの調整でやり過ごしていたが
根本的に問題を解決することができたので、スッキリ。

Split.jsの導入

画面分割ライブラリであるSplit.jsをお絵かきエリアに導入した。

参考:https://github.com/nathancahill/split/tree/master/packages/splitjs

インストール用コマンド

$ npm i split.js

TypeScript内でのインポート

import Split from 'split.js'

ただし、このままだとエラーが出たので
tsconfig.jsoncompilerOptionsに以下を追記

モジュールをどのように解決するのかを指定
"moduleResolution": "node"

参考:…Did you mean to set the ‘moduleResolution’ option to ‘node’, or to add aliases to the ‘paths’ option?と出た時の対処法 – Qiita

モジュールがdefault exportされていない場合はdefaultとして扱う
"esModuleInterop": true

参考:TypeScriptのesModuleinteropフラグを設定してCommonJSモジュールを実行可能とする | DevelopersIO

実装例

let sizes:any = localStorage.getItem('dotanimal-doteditor-split-sizes'); //LocalStrageの内容を参照
if (sizes) {
  sizes = JSON.parse(sizes);
} else {
  sizes = [50, 50] // デフォルトのサイズ
}
Split([
  '#workspace1Container', //分割対象となるセレクタを指定 
  '#workspace2Container',
  ], {
  sizes: sizes,
  minSize: 50, //画面の最小値
  maxSize: 501, //画面の最大値
  gutterSize: 16, //画面領域を変更するハンドルのサイズ
  snapOffset: 5, //ハンドルから画面端までの距離がここで指定した数値よりも下回ったらハンドルを画面端に吸着する
  direction:"horizontal", //分割の方向
  onDragEnd: function (sizes) {
    localStorage.setItem('dotanimal-doteditor-split-sizes', JSON.stringify(sizes)) //幅を変更するたびにLocalStrageに保存
  },
});

追加したイシュー


ひとこと

レイヤー機能の実装を具体的に検討し始めているが
レイヤーを操作するUI側の実装がかなり面倒になりそうな予感。