最初に書き出していた欲しい機能の最後の一つ、レイヤー機能を実装した。
作ったもの

レイヤーを制御するためのレイヤーパネルを追加。
これを操作することで、
・数の増減
・重なり順
・名称変更
・表示・非表示の切り替え
ができる。
お絵かきエリア側は見た目上の変更はない。
クラス図

レイヤーパネルを管理するLayerPanelControllerを追加。
レイヤーパネル内で各UIパーツを管理するために、
・LayerPanelItemクラス(レイヤー)
・Eyeクラス(レイヤーの表示・非表示のトグルを管理する「目」のアイコンのボタン)
・Txtクラス(レイヤー名を表示し、クリックで編集可能なテキスト)
も新たに作成し、
LayerPanelController.ts内に記載しているが、
クラスをexportしていないためクラス図に表示されていない。
つまづきポイント
Sortable.jsの導入
ドラッグ&ドロップでリストの並び替えができるライブラリ。
レイヤーパネル内で、レイヤーの重なり順を変更できるようにするために導入。
レイヤーパネル内で、レイヤーを示すUIの順番をドラッグ&ドロップで入れ替えられるようにするために導入。
参考:https://github.com/SortableJS/Sortable
インストール用コマンド
npm i @types/sortablejs
TypeScript内でのインポート
import Sortable from "sortablejs";
実装例
Sortable.create(
<HTMLElement>document.querySelector('#layerPanelBody > ul'), //Sortableを指定するリストのセレクタ
{
handle: '.layerPanelItemHandle', //ハンドルに指定する要素のセレクタ
animation: 200, //アニメーションのミリ秒
onSort: (e:Event) =>{ //リストが並び替え・追加・削除が行われたときに発火
let target : HTMLElement = <HTMLElement>e.target;
let items : HTMLCollection = target.children;
for (let i = 0; i < items.length; i++) {
let item:HTMLElement = <HTMLElement>items[i];
item.setAttribute("data-sotable-index", String(i));//アイテムの並び順の番号を「data-sotable-index」属性に設定
}
},
onEnd : (e:Event) => { //アイテムのドラッグが終力した時に発火
}
}
);
レイヤーの非表示設定追加に伴うデータフォーマットの修正
作業途中で保存されているデータを復元してみたところ、
前回の作業で非表示にしていたレイヤーが
表示されてしまっていることへの違和感から
急遽、非表示レイヤーのフラグを追加することにした。
最新のフォーマットは以下。

複数クラスを指定する際のSCSS構文
SASS
.A{
&.B{
}
}
コンパイル後
.A.B{
}
CSSでマウスカーソルを移動カーソルに変更
cursor : move;
参考:cursor – CSS: カスケーディングスタイルシート | MDN
追加したイシュー
ひとこと
レイヤーに関する実装は
重なり順を変更する箇所がかなり複雑になりそうで気がかりだったが、
UI側をほぼSortable.jsに任せられたので
当初想定していたよりはスムーズに実装できた。
