JavaScript
ドラッグ
JavaScriptUI

エレメントの四隅をマウスドラッグしてリサイズする(JavaScriptUI)

More than 1 year has passed since last update.

前回に引き続き、要素に対してマウスで操作します。エレメントの四隅をドラッグしてサイズを変更する動きを実装します。OSのウィンドウのように、四隅をドラッグして上下左右にリサイズできる操作を実現したいと思います。


実現したいこと

画面上の要素(エレメント)四隅にマウスオーバーでポインタ変更

四隅をドラッグすると、ポインタに合わせて要素がリサイズする

処理概要

以下のように、3種類のイベントハンドラをセットする

イベントハンドラが検知したら、指定したFunctionをディスパッチする

・マウスのボタンを押下した

・マウスのボタンを押下した状態から、解放した

・マウスのボタンを移動した


処理

上の処理概要で記述した内容を実装する

JavaScript(マウスのボタンを押下した)

JavaScript(マウスのボタンを押下した状態から、解放した)

let move_flg = "";

let move_start_x = 0;
let move_start_y = 0;
let lh_flg = "";
let ch_flg = "";
let rh_flg = "";
let lf_flg = "";
let rf_flg = "";

// start drag
window.onmousedown = (e) => {
const obj = document.getElementById("t");
if (e.toElement.id == "lh") {
lh_flg = "true";
move_start_x = parseInt(obj.style.left.replace("px","")) + parseInt(obj.style.width.replace("px",""));
move_start_y = parseInt(obj.style.top.replace("px","")) + parseInt(obj.style.height.replace("px",""));
} else if(e.toElement.id == "ch") {
ch_flg = "true";
move_start_x = event.clientX - parseInt(obj.style.left.replace("px",""));
move_start_y = event.clientY - parseInt(obj.style.top.replace("px",""));
} else if(e.toElement.id == "rh") {
rh_flg = "true";
move_start_x = parseInt(obj.style.left.replace("px",""));
move_start_y = parseInt(obj.style.top.replace("px","")) + parseInt(obj.style.height.replace("px",""));
} else if(e.toElement.id == "lf") {
lf_flg = "true";
move_start_x = parseInt(obj.style.left.replace("px","")) + parseInt(obj.style.width.replace("px",""));
move_start_y = parseInt(obj.style.top.replace("px",""));
} else if(e.toElement.id == "rf") {
rf_flg = "true";
move_start_x = parseInt(obj.style.left.replace("px",""));
move_start_y = parseInt(obj.style.top.replace("px",""));
}
// end drag
window.onmouseup = (e) => {
lh_flg = "";
ch_flg = "";
rh_flg = "";
lf_flg = "";
rf_flg = "";
}

JavaScript(マウスのボタンを移動した)

// drag

window.onmousemove = (e) => {
if(event.clientY )
if(lh_flg == "true") {
const obj = document.getElementById("t");
obj.style.position = "absolute";
obj.style.left = event.clientX + "px";
obj.style.width = parseInt(move_start_x) - event.clientX + "px";
obj.style.top = event.clientY + "px";
obj.style.height = parseInt(move_start_y) - event.clientY + "px";
} else if (ch_flg == "true") {
const obj = document.getElementById("t");
obj.style.position = "absolute";
obj.style.left = (event.clientX - move_start_x) + "px";
obj.style.top = (event.clientY - move_start_y) + "px";
} else if (rh_flg == "true") {
const obj = document.getElementById("t");
obj.style.position = "absolute";
obj.style.width = event.clientX - move_start_x + "px";
obj.style.top = event.clientY + "px";
obj.style.height = parseInt(move_start_y) - event.clientY + "px";
} else if(lf_flg == "true") {
const obj = document.getElementById("t");
obj.style.position = "absolute";
obj.style.left = event.clientX + "px";
obj.style.width = parseInt(move_start_x) - event.clientX + "px";
obj.style.height = event.clientY - parseInt(move_start_y) + "px";
} else if(rf_flg == "true") {
const obj = document.getElementById("t");
obj.style.position = "absolute";
obj.style.width = event.clientX - move_start_x + "px";
obj.style.height = event.clientY - parseInt(move_start_y) + "px";
}
}

HTML(四隅をドラッグするエレメント)

パーツごとにマウスの左クリックを識別できるよう、以下のように分割しました。

上左、上中央、上右

中左、中中央、中右

下左、下中央、下右

<div id="t" style="position:absolute;" >

<div style="width:100%;">
<div id="lh" style="background-color:#00008B;"></div>
<div id="rh" style="background-color:#00008B;"></div>
<div id="ch" style="background-color:#00008B;"></div>
</div>
<div style="width:100%;height:100%">
<div id="lb" style="background-color:#006400;"></div>
<div id="rb" style="background-color:#006400;"></div>
<div id="cb" style="background-color:#006400;"></div>
</div>
<div style="width:100%;">
<div id="lf" style="background-color:#F4A460;"></div>
<div id="rf" style="background-color:#F4A460;"></div>
<div id="cf" style="background-color:#F4A460;"></div>
</div>
</div>

サンプル_エレメントの四隅をマウスドラッグしてリサイズする(JavaScriptUI)

本処理のポイントは、上左、下左のリサイズ処理部分です。マウスポインタに合わせて、要素の大きさを変えますが、左側に伸ばす必要があります。

 左側に伸ばす場合は、マウスの座標をエレメントの左上座標に代入します。また、マウスの動きに合わせて要素の横幅、縦幅を変更する必要があります。(左に移動する場合は、要素を左に移動、移動した距離を取得して横幅を更新する形となります)

次回は、イベントオブジェクトを利用して、クリックイベントを付与したエレメントが重なりあっているケースなど、実施しようと考えています。