デスクトップの肝中の肝機能である、ウィンドウ間でのアイコン移動、または、デスクトップからのウィンドウ内へのアイコン移動を構築してみました。
最初に言っておきますが、これまでの処理ではうまく処理できなかったので、大幅にソース改編を行っています。
デモ
※デモは最新版が表示されています。該当のデモを見たい場合は、ソースをCloneしてコミットを戻してブラウザで表示して確認してください。
ソースコード
https://github.com/yugeta/web_desktop/
今回のCommitは"#15"です。
解説
今回のウィンドウを跨いだ(またいだ)アイコンの移動を行うに関して、これまで"pointermove"イベントを利用していましたが、
このイベントは、一度クリックしたエレメント(要素)をずっと引っ張り続ける仕様のため、移動時に別のウィンドウにマウスが重なったかどうかの判定ができない状態になります。
なので、"pointermove"を、"mousedown + mousemove + mouseup"の王道処理に移動することにしました。
大きく分けると、アイコンの移動、ウィンドウの移動、ウィンドウのりサイズ、の3点のみのイベント処理だったのと、それぞれも別のモジュールで処理をしていたので、イベントからの中間処理と、受け渡しするデータを作り直す程度でなんとか乗り切れました。
とは言っても、まあまあな改修ボリュームだったので、ソースコードでdiffを追うにはかなり厳しいので、出来上がりのコードのみを参照してもらうのがいいと思います。
そして、今回の難しポイントは、ウィンドウの中にあるアイコンをデスクトップ上に出したい時に、ウィンドウの中から外に出ないアイコンをどう処理するのかというやり方です。
これまでのアイコンの移動は、表示されているエレメントをそのまま動かしていたんですが、今回から、擬似的にインスタンスとしての、アイコン要素を新たに作って、それを手前に表示して、座標に合わせて動かすようにしています。
動き終わった時に、元のアイコンを移動先の座標に移動させて、インスタンスのエレメントを削除するという流れです。
デスクトップにある、settingアイコンを移動して、ウィンドウに入れる、ビフォーアフターを1枚画像にしてみましたが、中間にあるのが、インスタンス要素になっているというのが理解できれば、さほど難しくないのがわかるでしょう。
途中の処理で、アイコン自身が開いているウィンドウにアイコンを入れようとした時に、入れ子になるのでキャンセル処理を行っており、
その場合は、元のアイコンを移動させずにそのままの位置に保持する役割も果たしています。
難易度高いポイント
通常のOSでフォルダを開いている中にそのフォルダ自身のアイコンを入れようとしたらエラー表示が出て、巻き戻されてしまうあの処理ですが、
これは、アイコンと同じフォルダという条件だけじゃなく、複数の階層が出来上がっている時に、上位階層に自身が存在しないかという点も考慮する必要があるので、
それを、js/icon/move.js の中の"get_parent_id_array()"という関数で、上位の階層を配列で取得して、
アイコン自身がその中に含まれていないか?という処理を行って対応しています。
階層での考え方が難しい人は、再帰処理をちゃんと理解できていないのかもしれないので、この処理は少し難しく感じてしまうかもしれませんね。
あとがき
ウィンドウを開いてアイコンを出し入れできるようにすると、デスクトップが整理できる反面、いまどういう状態になっているのかがわかりにくくなってしまいます。
それを回避するために、上部のヘッダメニューの「メニュ−」の中に「データ初期化」を行えるようにしました。
これをすると、ストレージに保存されているデータを全て消して、最初にアクセスした状態に戻すことができます。
このwebデスクトップが正式版になった際には、この機能は取り去るかもしれませんが、開発途中は、何度も頻繁に使う機能なので、このタイミングで投入しておきました。
デバッグしたい人は是非この機能を使って、色々と弄ってみてください。
0 件のコメント:
コメントを投稿