I know this is an old question, I arrived here from this other question that was marked as a duplicate of this one, and wanted to add a possible solution that doesn’t require jQuery or any libraries, and that works in all major browsers. It is based on this tutorial recommended by @AmirHossein Mehrvarzi.
This small solution doesn’t use the drag events, just the mousedown
, mouseup
and mousemove
. This is how it works:
- When the mouse is down on the rectangle, it saves the mouse position and the active element.
- When the mouse moves, the rectangle coordinates are updated with the new mouse position.
- When the mouse is up, it resets the active element.
From the code in the question above:
var selectedElement = null;
var currentX = 0;
var currentY = 0;
$(document).ready(function() {
function handleDragStart(e) {
log("handleDragStart");
this.style.opacity = '0.4'; // this ==> e.target is the source node.
};
var registercb = function () {
$("#cvs > rect").mousedown(function (e) {
// save the original values when the user clicks on the element
currentX = e.clientX;
currentY = e.clientY;
selectedElement = e.target;
}).mousemove(function (e) {
// if there is an active element, move it around by updating its coordinates
if (selectedElement) {
var dx = parseInt(selectedElement.getAttribute("x")) + e.clientX - currentX;
var dy = parseInt(selectedElement.getAttribute("y")) + e.clientY - currentY;
currentX = e.clientX;
currentY = e.clientY;
selectedElement.setAttribute("x", dx);
selectedElement.setAttribute("y", dy);
}
}).mouseup(function (e) {
// deactivate element when the mouse is up
selectedElement = null;
});
};
function log() {
if (window.console && window.console.log)
window.console.log('[XXX] ' + Array.prototype.join.call(arguments, ' '));
};
registercb();
});
rect { cursor: move; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1>SVG/HTML 5 Example</h1>
<svg id="cvs">
<rect x="0" y="10" width="100" height="80" fill="#69c" />
<rect x="50" y="50" width="90" height="50" fill="#c66" />
</svg>
You can also see it on this JSFiddle: http://jsfiddle.net/YNReB/61/
If you want to add drop functionality, you can modify the mouseup
function to read the element on the cursor position (with document.elementFromPoint(e.clientX, e.clientY)
) and then you can perform actions on the original element and the one where it was dropped.