Core JavaScript

SVG - A Draggable Line

The acronym SVG stands for Scalable Vector Graphics and refers to graphics that are generated by a geometric specification rather than by pixels, like an image (called rasterized graphics as opposed to the vectorized graphics described here).

The program below fetches the body element first. Then a div element is created and assigned the name qMainDiv. Inside qMainDiv, we add a svg element and put the line element inside it.

The code creates a line that has endpoints that can be dragged. Also, the cursor changes when it is close enough to a endpoint to signal that the endpoint may be dragged.

SvgDraggableLine.html

<!DOCTYPE html>
<html>
<head>
    <title>XoaX.net's Javascript</title>
</head>
<body>
    <script type="text/javascript" src="SvgDraggableLine.js"></script>
</body>
</html>

SvgDraggableLine.js

var qBody = document.getElementsByTagName("body")[0];

var qMainDiv = document.createElement("div");
qMainDiv.style.backgroundColor = "#bbdd99";
qMainDiv.style.width = "600px";
qMainDiv.style.height = "600px";
qMainDiv.style.margin = "20px";
qMainDiv.mbDrag1 = false;
qMainDiv.mbDrag2 = false;
qMainDiv.onmousemove = function(e) {
	this.SetCursorCoordinates(e);
	this.SetCursorDistancesSquared();
	if (this.mbDrag1) {
		this.mqLine.setAttribute('x1', this.mdCursorX);
		this.mqLine.setAttribute('y1', this.mdCursorY);
	} else if (this.mbDrag2){
		this.mqLine.setAttribute('x2', this.mdCursorX);
		this.mqLine.setAttribute('y2', this.mdCursorY);
	}
	if ((this.mdDistSq1 <= 25) || (this.mdDistSq2 <= 25)) {
		this.style.cursor = "pointer";
	} else {
		this.style.cursor = "auto";
	}
};
qMainDiv.onmousedown = function(e) {
	this.SetCursorCoordinates(e);
	this.SetCursorDistancesSquared();
	// Check if either point is in range to be dragged
	if (this.mdDistSq1 <= 25) {
		this.mbDrag1 = true;
	} else if (this.mdDistSq2 <= 25) {
		this.mbDrag2 = true;
	}
};
qMainDiv.onmouseup = function(e) {
	this.mbDrag1 = false;
	this.mbDrag2 = false;
};
qMainDiv.SetCursorCoordinates = function(e) {
	var dElementOffsetX = 0;
	var dElementOffsetY = 0;
	var qElement = this;

	do{
	    dElementOffsetX += qElement.offsetLeft - qElement.scrollLeft;
	    dElementOffsetY += qElement.offsetTop - qElement.scrollTop;
	    qElement = qElement.offsetParent
	} while(qElement != document.body)

	this.mdCursorX = e.pageX - dElementOffsetX;
	this.mdCursorY = e.pageY - dElementOffsetY;
}
qMainDiv.SetCursorDistancesSquared = function() {
	var dX1 = this.mqLine.getAttribute('x1');
	var dY1 = this.mqLine.getAttribute('y1');
	var dX2 = this.mqLine.getAttribute('x2');
	var dY2 = this.mqLine.getAttribute('y2');
	this.mdDistSq1 = (dX1 - this.mdCursorX)*(dX1 - this.mdCursorX)
		+ (dY1 - this.mdCursorY)*(dY1 - this.mdCursorY);
	this.mdDistSq2 = (dX2 - this.mdCursorX)*(dX2 - this.mdCursorX)
		+ (dY2 - this.mdCursorY)*(dY2 - this.mdCursorY);
}

var qLineSvg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
qLineSvg.style.width="600px";
qLineSvg.style.height="600px";

qMainDiv.mqLineSvg = qLineSvg;

var qLine = document.createElementNS("http://www.w3.org/2000/svg", "line");
qLine.setAttribute('x1', '120');
qLine.setAttribute('y1', '220');
qLine.setAttribute('x2', '460');
qLine.setAttribute('y2', '140');
qLine.setAttribute('stroke-width', '3');
qLine.setAttribute('stroke', 'rgb(240, 255, 220)');

qMainDiv.mqLine = qLine;

qLineSvg.appendChild(qLine);
qMainDiv.appendChild(qLineSvg);
qBody.appendChild(qMainDiv);
 

Output

 
 

© 2007–2024 XoaX.net LLC. All rights reserved.