昨日の続き。 カードの移動を考える。
本家では、列から列へのカードの移動は、ドラッグ/ドロップになっている。 移動するときの手順を分解すると、大雑把に次の3操作。
このそれぞれでやる処理の詳細は、準備も含めて大体次の通りになるだろう。
マウスボタンが押されたときに処理が実行できるように、イベント処理を設定しておく。 ただし、イベント処理をどう設定するかは考えるところ。 例えば、
移動元でマウスボタンが押されたとき、列の先頭からカーソル位置のカードまでが、同じマークの連番昇順であるかどうかを判定する。 この条件を満たしていれば、移動可能として次の処理を行う。
条件を満たさなかった場合にどうするかは、上記の準備をどのパターンで実装するかによる。 クリックイベントの中で判定する場合は、 「条件を満たさなければ何もしない」 という処理をすることになる。 移動可能なカードのみイベント処理を設定する場合は、条件を満たさない場合は本当に何もしなくていい。
マウスカーソルの移動に対してドラッグのためのイベント処理を設定する。 ここで、ドラッグを 「移動対象のカードとマウスカーソルの相対位置を保つこと」 と考えて、実際の処理をもう少し細かくすると、
となるだろう。
上記イベント処理を行う。
マウスボタンを離したとき、そこにカードを移動できるかどうかは、次の条件を満たすかどうか。
上記判定の結果で処理が分かれる。
と、ここまで考えたところで方針転換。 俺はこのドラッグ/ドロップ方式がどうも好きじゃないのだ。 マウスを使うときはこれでもいいのだが、トラックパッドだと幅が足りなくてやり直しになることもしばしば。 ということで、移動元と移動先をクリックで決めることにした。 具体的にはこんな感じ。
表向きのカードにイベント処理を設定する。 イベント処理のタイミングは上に同じ。
移動元を選択中かどうかで処理を分ける。
今回選択した列が移動元と同じかどうかで処理を分ける。
カード移動可否判定(移動先)を行う。
移動先として選択した列にカードがあるかどうかで処理を分ける。
仮の移動対象に、列の先頭のカードより1少ないカードが有ること。 有れば、仮の移動対象の先頭からそのカードまでを、実際の移動対象とする。
仮の移動対象の全てを、実際の移動対象とする。
選択中のうちで移動できるものを全て移動するのは、その方が操作性がいいような気がしたから。 移動元と先の列の選択で、移動できるものを全て移動することも考えたが、これだと分割して移動することが出来ない。 かと言って、いつもいつも移動できるものをきっちり選択するのも、iPhone なんかの小さい画面だとかなり面倒。 で、間を取ってこの仕様。
おっと、カードにイベント処理を設定していると、カードがなくなって列が空になった時に、その列を移動先に指定できなくなるじゃないか。 うーん…
列のカードだけでなく、列そのものにイベント処理を設定するか。 いや、いっそイベント処理はカードではなく列に持たせるか。 カードを配置するエリアを包含するようにdivを設定して、伝播してきたイベントを処理するとか。 あ、でも、これだとカードの移動がDOMの要素ツリーの組み替えになって面倒そうだな。 うーん…
列を本当に空にするのではなく、一番下に移動できないダミーのカードを置いて、これが先頭のときを空と判断するか。 これならカードだけで統一的に扱えるし。 でも、ダミーのカードってのが、なんだかなぁ。 あ、でも本家のは、列が空になったら枠が見えるようになっているから、ダミーのカードをこの枠に見立てればいいのか。 ダミーのカードを、数字もマークも無い枠だけの白いカードとしておけば、きっと枠に見えるだろう。 いや、見えるか見えないかじゃない。 見るのだ。
と、決意を新たにして、今日はここまで。