😎
複数のSVGの図形をマウスドラッグで移動するサンプル
はじめに
SVGで描画ツールを作りたくて、JavaScriptでSVGを操作するサンプルを作成中。今回は複数の四角形をドラッグで移動するサンプルスクリプトまでを備忘録として残します。
スクリプトソース
ソースはgithubに置いてます。
この記事で紹介するスクリプトは上記リポジトリにある以下3つ。タイトルのスクリプトは3つ目です。
- 01_DrawRectanglesWithJS.html
- → 01_JavaScriptでSVGの四角形を描画する
- 02_SelectARectangleWithButtons.html
- → 02_ボタンで選択したSVGの四角形を移動する
- 03_SelectAndMoveTheRectangleWithTheMouse.html
- → 03_複数のSVGの図形をマウスドラッグで移動する
3つ目のデモ動画
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が作れるよう開発はつづく
Discussion