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 cubic bezier curve that interpolates the endpoints and has two control points that can be dragged. Also, the cursor changes when it is close enough to a one of these points to signal that it may be dragged.
<!DOCTYPE html> <html> <head> <title>XoaX.net's Javascript</title> </head> <body> <script type="text/javascript" src="SvgDraggableCubic.js"></script> </body> </html>
var qBody = document.getElementsByTagName("body")[0]; // The containing div and all of the variables 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.mbDragC1 = false; qMainDiv.mbDragC2 = false; qMainDiv.mdX1 = 100.0; qMainDiv.mdY1 = 200.0; qMainDiv.mdXC1 = 100.0; qMainDiv.mdYC1 = 100.0; qMainDiv.mdXC2 = 300.0; qMainDiv.mdYC2 = 100.0; qMainDiv.mdX2 = 300.0; qMainDiv.mdY2 = 200.0; qMainDiv.mdDistSq1 = 200.0; qMainDiv.mdDistSqC1 = 200.0; qMainDiv.mdDistSqC2 = 200.0; qMainDiv.mdDistSq2 = 200.0; qMainDiv.mqPoint1 = null; qMainDiv.mqPointC1 = null; qMainDiv.mqPointC2 = null; qMainDiv.mqPoint2 = null; qMainDiv.mqCubicSvg = null; qMainDiv.mqCubicPath = null; qMainDiv.mqLinePath = null; qMainDiv.onmousemove = function(e) { this.SetCursorCoordinates(e); this.SetCursorDistancesSquared(); // Make a case for draging each of the four points if (this.mbDrag1) { this.mdX1 = this.mdCursorX; this.mdY1 = this.mdCursorY; this.mqPoint1.setAttribute('cx', this.mdX1); this.mqPoint1.setAttribute('cy', this.mdY1); } else if (this.mbDrag2){ this.mdX2 = this.mdCursorX; this.mdY2 = this.mdCursorY; this.mqPoint2.setAttribute('cx', this.mdX2); this.mqPoint2.setAttribute('cy', this.mdY2); } else if (this.mbDragC1){ this.mdXC1 = this.mdCursorX; this.mdYC1 = this.mdCursorY; this.mqPointC1.setAttribute('cx', this.mdXC1); this.mqPointC1.setAttribute('cy', this.mdYC1); } else if (this.mbDragC2){ this.mdXC2 = this.mdCursorX; this.mdYC2 = this.mdCursorY; this.mqPointC2.setAttribute('cx', this.mdXC2); this.mqPointC2.setAttribute('cy', this.mdYC2); } else { // If the cursor is close to a drag point, change it. if ((this.mdDistSq1 <= 25) || (this.mdDistSqC1 <= 25) || (this.mdDistSqC2 <= 25) || (this.mdDistSq2 <= 25)) { this.style.cursor = "pointer"; } else { this.style.cursor = "auto"; } } this.mqLinePath.setAttribute('d', 'M'+this.mdX1+','+this.mdY1+ ' L'+this.mdXC1+','+this.mdYC1+' L'+this.mdXC2+','+this.mdYC2+ ' L'+this.mdX2+','+this.mdY2); this.mqCubicPath.setAttribute('d', 'M'+this.mdX1+','+this.mdY1+ ' C'+this.mdXC1+','+this.mdYC1+' '+this.mdXC2+','+this.mdYC2+ ' '+this.mdX2+','+this.mdY2); }; qMainDiv.onmousedown = function(e) { this.SetCursorCoordinates(e); this.SetCursorDistancesSquared(); // Check if any point is in range to be dragged if (this.mdDistSq1 <= 25) { this.mbDrag1 = true; } else if (this.mdDistSqC1 <= 25) { this.mbDragC1 = true; } else if (this.mdDistSqC2 <= 25) { this.mbDragC2 = true; } else if (this.mdDistSq2 <= 25) { this.mbDrag2 = true; } }; qMainDiv.onmouseup = function(e) { this.mbDrag1 = false; this.mbDragC1 = false; this.mbDragC2 = false; this.mbDrag2 = false; }; // The function that is used to calculate the cursor coordinates 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.mdX1; var dY1 = this.mdY1; var dXC1 = this.mdXC1; var dYC1 = this.mdYC1; var dXC2 = this.mdXC2; var dYC2 = this.mdYC2; var dX2 = this.mdX2; var dY2 = this.mdY2; // Calculate the distance squared from the cursor to each point this.mdDistSq1 = (dX1 - this.mdCursorX)*(dX1 - this.mdCursorX) + (dY1 - this.mdCursorY)*(dY1 - this.mdCursorY); this.mdDistSqC1 = (dXC1 - this.mdCursorX)*(dXC1 - this.mdCursorX) + (dYC1 - this.mdCursorY)*(dYC1 - this.mdCursorY); this.mdDistSqC2 = (dXC2 - this.mdCursorX)*(dXC2 - this.mdCursorX) + (dYC2 - this.mdCursorY)*(dYC2 - this.mdCursorY); this.mdDistSq2 = (dX2 - this.mdCursorX)*(dX2 - this.mdCursorX) + (dY2 - this.mdCursorY)*(dY2 - this.mdCursorY); } // The whole SVG region var qCubicSvg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); qCubicSvg.style.width="600px"; qCubicSvg.style.height="600px"; qMainDiv.mqCubicSvg = qCubicSvg; // The cubic interpolation path var qCubicPath = document.createElementNS("http://www.w3.org/2000/svg", "path"); qCubicPath.setAttribute('d', 'M'+qMainDiv.mdX1+','+qMainDiv.mdY1+ ' C'+qMainDiv.mdXC1+','+qMainDiv.mdYC1+ ' '+qMainDiv.mdXC2+','+qMainDiv.mdYC2+ ' '+qMainDiv.mdX2+','+qMainDiv.mdY2); qCubicPath.setAttribute('stroke-width', '3'); qCubicPath.setAttribute('stroke', 'rgb(240, 255, 220)'); qCubicPath.setAttribute('fill', 'none'); qMainDiv.mqCubicPath = qCubicPath; // The three-piece linear path bounding the quadratic var qLinePath = document.createElementNS("http://www.w3.org/2000/svg", "path"); qLinePath.setAttribute('d', 'M'+qMainDiv.mdX1+','+qMainDiv.mdY1+ ' L'+qMainDiv.mdXC1+','+qMainDiv.mdYC1+ ' L'+qMainDiv.mdXC2+','+qMainDiv.mdYC2+ ' L'+qMainDiv.mdX2+','+qMainDiv.mdY2); qLinePath.setAttribute('stroke-width', '1'); qLinePath.setAttribute('stroke', 'rgb(240, 255, 220)'); qLinePath.setAttribute('fill', 'none'); qMainDiv.mqLinePath = qLinePath; // The first endpoint var qPoint1 = document.createElementNS("http://www.w3.org/2000/svg", "circle"); qPoint1.setAttribute('cx', qMainDiv.mdX1); qPoint1.setAttribute('cy', qMainDiv.mdY1); qPoint1.setAttribute('r', 4); qPoint1.setAttribute('fill', 'rgb(240, 255, 220)'); qMainDiv.mqPoint1 = qPoint1; // The first control point var qPointC1 = document.createElementNS("http://www.w3.org/2000/svg", "circle"); qPointC1.setAttribute('cx', qMainDiv.mdXC1); qPointC1.setAttribute('cy', qMainDiv.mdYC1); qPointC1.setAttribute('r', 4); qPointC1.setAttribute('fill', 'rgb(240, 255, 220)'); qMainDiv.mqPointC1 = qPointC1; // The second control point var qPointC2 = document.createElementNS("http://www.w3.org/2000/svg", "circle"); qPointC2.setAttribute('cx', qMainDiv.mdXC2); qPointC2.setAttribute('cy', qMainDiv.mdYC2); qPointC2.setAttribute('r', 4); qPointC2.setAttribute('fill', 'rgb(240, 255, 220)'); qMainDiv.mqPointC2 = qPointC2; // The second endpoint var qPoint2 = document.createElementNS("http://www.w3.org/2000/svg", "circle"); qPoint2.setAttribute('cx', qMainDiv.mdX2); qPoint2.setAttribute('cy', qMainDiv.mdY2); qPoint2.setAttribute('r', 4); qPoint2.setAttribute('fill', 'rgb(240, 255, 220)'); qMainDiv.mqPoint2 = qPoint2; // Put all of the elements together qCubicSvg.appendChild(qCubicPath); qCubicSvg.appendChild(qLinePath); qCubicSvg.appendChild(qPoint1); qCubicSvg.appendChild(qPointC1); qCubicSvg.appendChild(qPointC2); qCubicSvg.appendChild(qPoint2); qMainDiv.appendChild(qCubicSvg); qBody.appendChild(qMainDiv);
© 20072024 XoaX.net LLC. All rights reserved.