😎

複数のSVGの図形をマウスドラッグで移動するサンプル

2022/02/14に公開

はじめに

SVGで描画ツールを作りたくて、JavaScriptでSVGを操作するサンプルを作成中。今回は複数の四角形をドラッグで移動するサンプルスクリプトまでを備忘録として残します。

スクリプトソース

ソースはgithubに置いてます。

https://github.com/zgw426/SVG-JavaScript-MySamples

この記事で紹介するスクリプトは上記リポジトリにある以下3つ。タイトルのスクリプトは3つ目です。

  • 01_DrawRectanglesWithJS.html
    • 01_JavaScriptでSVGの四角形を描画する
  • 02_SelectARectangleWithButtons.html
    • 02_ボタンで選択したSVGの四角形を移動する
  • 03_SelectAndMoveTheRectangleWithTheMouse.html
    • 03_複数のSVGの図形をマウスドラッグで移動する

3つ目のデモ動画

https://youtu.be/7x4xVxVobWA

01_JavaScriptでSVGの四角形を描画する

四角形を描画するJavaScriptです。
関数svgRect()が四角形を描画する関数です。
変数objsが描画する四角形のパラメータ群です。

01_DrawRectanglesWithJS.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8"/>
<script>
let SvgArea = 'svgArea';
let objs = [
    { "x": 100, "y": 100, "w":100, "h":100, color: "#ABC1FF", opacity: "0.8", label: "FUGA" },
    { "x": 200, "y": 200, "w":70, "h":50, color: "#FF02AB", opacity: "0.5", label: "HOGE" },
]
function svgRect(svgFld,x,y,w,h,color,opa,id){
    this.rect=document.createElementNS("http://www.w3.org/2000/svg","rect");
    this.rect.setAttributeNS(null,"x",x);
    this.rect.setAttributeNS(null,"y",y);
    this.rect.setAttributeNS(null,"width",w);
    this.rect.setAttributeNS(null,"height",h);
    this.rect.setAttributeNS(null,"fill", color);
    this.rect.setAttributeNS(null,"fill-opacity", opa);
    this.rect.setAttributeNS(null,"id", id);
    document.getElementById(svgFld).appendChild(this.rect);
}
window.onload = function() {
    for (let i in objs) {
        console.log(objs[i]);
        iId      = i;
        iX       = objs[i]["x"];
        iY       = objs[i]["y"];
        iW       = objs[i]["w"];
        iH       = objs[i]["h"];
        iColor   = objs[i]["color"];
        iOpacity = objs[i]["opacity"];
        iLabel      = objs[i]["label"];
        svgRect(SvgArea,iX,iY,iW,iH,iColor,iOpacity,iId);
    }
}
</script>
</head>
<body>
<svg width="1000" height="400" id="svgArea"></svg>
</body>
</html>

以下は四角形のパラメータ群を抜粋です。

四角形のパラメータ群
objs = [
    { "x": 100, "y": 100, "w":100, "h":100, color: "#ABC1FF", opacity: "0.8", label: "FUGA" },
    { "x": 200, "y": 200, "w":70, "h":50, color: "#FF02AB", opacity: "0.5", label: "HOGE" },
]

各パラメータの意味

パラメータ 意味
x 四角形のX座標
y 四角形のY座標
w 四角形の幅
h 四角形の高さ
color 四角形の色
opacity 四角形の透明度
label ラベル(今は無意味)

四角形を1つ追加して3つ描画する例

四角形のパラメータ群
objs = [
    { "x": 100, "y": 100, "w":100, "h":100, color: "#ABC1FF", opacity: "0.8", label: "FUGA" },
    { "x": 200, "y": 200, "w":70, "h":50, color: "#FF02AB", opacity: "0.5", label: "HOGE" },
    { "x": 300, "y": 100, "w":80, "h":70, color: "#0202AB", opacity: "0.9", label: "KOME" },
]

02_ボタンで選択したSVGの四角形を移動する

赤い四角形,青い四角形,,とかかれたボタンを描画します。
赤ボタンをクリックすると赤い四角形をマウスドラッグで移動できます。
青ボタンをクリックすると青い四角形をマウスドラッグで移動できます。

02_SelectARectangleWithButtons.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8"/>
<style>
	<!--
	svg {
		border:solid 1px #a02180;
	}
	* {
		margin: 0px;
		padding: 0px;
	}
	-->
</style>
<script>
let drag = {isMouseDown : false,target : null,offsetx : 0,offsety : 0,}
let rectArr = new Array();
let rects   = ["rect1", "rect2"];

document.onmouseup = function () {
	drag.isMouseDown = false;
}
document.onmousemove = function( e ) {
    if (drag.isMouseDown == true) {
		drag.target.x.baseVal.value = e.clientX - drag.offsetx;
		drag.target.y.baseVal.value = e.clientY - drag.offsety;
	}
}
function draggable( element ) {
	element.addEventListener('mousedown', function( e ) {
		console.log("aaa");
		e.preventDefault();
		var rect = element.getBoundingClientRect();
		drag.offsetx = e.clientX - rect.left;
		drag.offsety = e.clientY - rect.top;;
		drag.isMouseDown = true;
		return false;
	});
}
window.onload = function() {
	rectArr[0] = document.getElementById( rects[0] );
	rectArr[1] = document.getElementById( rects[1] );
}
function clickButton(argButton){
	draggable(rectArr[ argButton ]);
	drag.target = rectArr[ argButton ];
}

</script>
</head>
<body>
<svg width="1000" height="400">
	<rect id="rect1" x="10"  y="10"  width="100" height="70"  fill="blue" />
	<rect id="rect2" x="150" y="150" width="50"  height="170" fill="red" />
</svg>
<BR>
<input type="button" value="" onClick="clickButton(0)">
<input type="button" value="" onClick="clickButton(1)">
</body>
</html>

03_複数のSVGの図形をマウスドラッグで移動する

4つの四角形を描画し、マウスでドラッグした図形を移動します。

03_SelectAndMoveTheRectangleWithTheMouse.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8"/>
<style>
<!--
* { margin: 0px; padding: 0px; }
svg { border:solid 1px #a02180; }
-->
</style>
<script>
let SvgArea = 'svgArea'; // SVGタグのID
// objs : 描画する四角形のパラメータ
let objs = [
    { "x": 10,  "y": 10, "w":100, "h":100, color: "#ABC1FF", opacity: "0.8", label: "FUGA" },
    { "x": 200, "y": 30, "w":100, "h":100, color: "#FF02AB", opacity: "0.5", label: "HOGE" },
    { "x": 300, "y": 10, "w":50,  "h":50,  color: "#FFABC1", opacity: "0.9", label: "PIYO" },
    { "x": 400, "y": 30, "w":50,  "h":50,  color: "#991122", opacity: "1.0", label: "MATE" },
]
let tgtRect;
let tgtId; // マウスクリックしたときに選択した四角形(rect)のID
let drag = {isMouseDown : false, id : null, target : null,offsetx : 0,offsety : 0,} // 移動する四角形(rect)の情報

//SVG Rect(四角形) を作る
function svgRect(svgFld,x,y,w,h,color,opa,id){
    this.rect=document.createElementNS("http://www.w3.org/2000/svg","rect");
    this.rect.setAttributeNS(null,"x",x);
    this.rect.setAttributeNS(null,"y",y);
    this.rect.setAttributeNS(null,"width",w);
    this.rect.setAttributeNS(null,"height",h);
    this.rect.setAttributeNS(null,"fill", color);
    this.rect.setAttributeNS(null,"fill-opacity", opa);
    this.rect.setAttributeNS(null,"id", id);
    document.getElementById(svgFld).appendChild(this.rect);
}
document.onmouseup = function () {
	drag.isMouseDown = false;
	drag.target = null;
}
document.onmousemove = function( e ) {
    if (drag.target != null) {
	drag.target.x.baseVal.value = e.clientX - drag.offsetx;
	drag.target.y.baseVal.value = e.clientY - drag.offsety;
        objs[ drag.id ]["x"] = drag.target.x.baseVal.value;
        objs[ drag.id ]["y"] = drag.target.y.baseVal.value;
    }
}
document.onmousedown = function( e ) {
    eX = e.pageX;
    eY = e.pageY;
    for (let i in objs) {
        iId    = i;
        iXmin  = objs[i]["x"];
        iXmax  = objs[i]["x"] + objs[i]["w"];
        iYmin  = objs[i]["y"];
        iYmax  = objs[i]["y"] + objs[i]["h"];

        if (iXmin <= eX && eX < iXmax){ // マウスポインタのX座標が図形の範囲内にあるか?
            if (iYmin <= eY && eY < iYmax){ // マウスポインタのX座標が図形の範囲内にある場合、Y座標は範囲内にあるか?
                tgtId = Number(iId);
                tgtRect = document.getElementById( iId );
                drag.id = tgtId;
                drag.target = tgtRect;
                drag.offsetx = e.clientX - objs[ tgtId ]["x"];
                drag.offsety = e.clientY - objs[ tgtId ]["y"];
                drag.isMouseDown = true;
                break;
            }
        }
    }
}

window.onload = function() {
    for (let i in objs) { // 四角形を描画
        iId      = i;
        iX       = objs[i]["x"];
        iY       = objs[i]["y"];
        iW       = objs[i]["w"];
        iH       = objs[i]["h"];
        iColor   = objs[i]["color"];
        iOpacity = objs[i]["opacity"];
	iLabel   = objs[i]["label"]
        svgRect(SvgArea,iX,iY,iW,iH,iColor,iOpacity,iId);
    }
}
</script>
</head>
<body>
<svg width="1000" height="200" id="svgArea"></svg>
</body>
</html>

今回はここまで。03のサンプル作るのに思った以上に手こずった。描画ツールを作るため、もっと複雑なUIが作れるよう開発はつづく

つづき→ 複数のSVGの図形をマウスドラッグで移動&変形するサンプルスクリプト

Discussion