-
-
Save thebinarypenguin/1558194 to your computer and use it in GitHub Desktop.
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Movable and Re-sizable Raphael JS Shape</title> | |
</head> | |
<body> | |
<div id="paper"></div> | |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> | |
<script src="http://github.com/DmitryBaranovskiy/raphael/raw/master/raphael-min.js"></script> | |
<script> | |
(function() { | |
var dragStart = function() { | |
// Save some starting values | |
this.ox = this.attr('x'); | |
this.oy = this.attr('y'); | |
this.ow = this.attr('width'); | |
this.oh = this.attr('height'); | |
this.dragging = true; | |
}; | |
var dragMove = function(dx, dy) { | |
// Inspect cursor to determine which resize/move process to use | |
switch (this.attr('cursor')) { | |
case 'nw-resize' : | |
this.attr({ | |
x: this.ox + dx, | |
y: this.oy + dy, | |
width: this.ow - dx, | |
height: this.oh - dy | |
}); | |
break; | |
case 'ne-resize' : | |
this.attr({ | |
y: this.oy + dy , | |
width: this.ow + dx, | |
height: this.oh - dy | |
}); | |
break; | |
case 'se-resize' : | |
this.attr({ | |
width: this.ow + dx, | |
height: this.oh + dy | |
}); | |
break; | |
case 'sw-resize' : | |
this.attr({ | |
x: this.ox + dx, | |
width: this.ow - dx, | |
height: this.oh + dy | |
}); | |
break; | |
default : | |
this.attr({ | |
x: this.ox + dx, | |
y: this.oy + dy | |
}); | |
break; | |
} | |
}; | |
var dragEnd = function() { | |
this.dragging = false; | |
}; | |
var changeCursor = function(e, mouseX, mouseY) { | |
// Don't change cursor during a drag operation | |
if (this.dragging === true) { | |
return; | |
} | |
// X,Y Coordinates relative to shape's orgin | |
var relativeX = mouseX - $('#paper').offset().left - this.attr('x'); | |
var relativeY = mouseY - $('#paper').offset().top - this.attr('y'); | |
var shapeWidth = this.attr('width'); | |
var shapeHeight = this.attr('height'); | |
var resizeBorder = 10; | |
// Change cursor | |
if (relativeX < resizeBorder && relativeY < resizeBorder) { | |
this.attr('cursor', 'nw-resize'); | |
} else if (relativeX > shapeWidth-resizeBorder && relativeY < resizeBorder) { | |
this.attr('cursor', 'ne-resize'); | |
} else if (relativeX > shapeWidth-resizeBorder && relativeY > shapeHeight-resizeBorder) { | |
this.attr('cursor', 'se-resize'); | |
} else if (relativeX < resizeBorder && relativeY > shapeHeight-resizeBorder) { | |
this.attr('cursor', 'sw-resize'); | |
} else { | |
this.attr('cursor', 'move'); | |
} | |
}; | |
// Create drawing area | |
var paper = Raphael("paper", 500, 500); | |
// Add a rectangle | |
var shapes = paper.add([{ | |
'type' : 'rect', | |
'x' : 150, | |
'y' : 150, | |
'width' : 100, | |
'height' : 80, | |
'fill' : '#759dcd', | |
'stroke' : '#3b5068', | |
'stroke-width' : 10 | |
}]); | |
// Attach "Mouse Over" handler to rectangle | |
shapes[0].mousemove(changeCursor); | |
// Attach "Drag" handlers to rectangle | |
shapes[0].drag(dragMove, dragStart, dragEnd); | |
})(); | |
</script> | |
</body> | |
</html> |
What license is this code under? Would prefer MIT/BSD or LGPL. I'm looking to use in an LGPL project myself. Very nice code.
The Raphaël library (and my code) both use the MIT license.
You my friend, are amazing! Thank you so much for this excellent code and for releasing it under the MIT license.
Beautiful. Thank you. I will treat your code with love and respect.
Hello, with the version 2.1.2, it´s could be an plugin:
(function(){
/* Necesita Jquery y Raphael */
Raphael.el.movible=function (paper) {
this.mousemove(this.dragMoving);
this.drag(this.dragMove, this.dragStart, this.dragEnd);
};
Raphael.el.dragStart = function() {
// Save some starting values
this.ox = this.attr('x');
this.oy = this.attr('y');
this.ow = this.attr('width');
this.oh = this.attr('height');
this.dragging = true;
};
Raphael.el.dragMove = function(dx, dy) {
switch (this.attr('cursor')) {
case 'nw-resize' : this.attr({ x: this.ox + dx, y: this.oy + dy, width: this.ow - dx, height: this.oh - dy }); break;
case 'ne-resize' : this.attr({ y: this.oy + dy , width: this.ow + dx, height: this.oh - dy}); break;
case 'se-resize' : this.attr({ width: this.ow + dx, height: this.oh + dy }); break;
case 'sw-resize' : this.attr({ x: this.ox + dx, width: this.ow - dx, height: this.oh + dy});break;
default : this.attr({ x: this.ox + dx, y: this.oy + dy});break;
}
};
Raphael.el.dragEnd = function() { this.dragging = false;};
Raphael.el.dragMoving = function(e, mouseX, mouseY) {
if (this.dragging === true) {return;}
// X,Y Coordinates relative to shape's orgin
var relativeX = mouseX - this.paper._left - this.attr('x');
var relativeY = mouseY - this.paper._top - this.attr('y');
var shapeWidth = this.attr('width');
var shapeHeight = this.attr('height');
var resizeBorder = 10;
if (relativeX < resizeBorder && relativeY < resizeBorder) { this.attr('cursor', 'nw-resize');}
else if (relativeX > shapeWidth-resizeBorder && relativeY < resizeBorder) {this.attr('cursor', 'ne-resize');}
else if (relativeX > shapeWidth-resizeBorder && relativeY > shapeHeight-resizeBorder) {this.attr('cursor', 'se-resize');}
else if (relativeX < resizeBorder && relativeY > shapeHeight-resizeBorder) {this.attr('cursor', 'sw-resize');}
else { this.attr('cursor', 'move');}
};
})();
Comments?
thank's!!!!
Hoy can I apply this on paper.text?
To prevent rectangle resize and drag out of paper border, use the following snippet below:
/**
* GETTER / SETTER METHOD(s)
* */
getX(rect, ddx) {
var width = rect.paper.width,
thisBox = rect.getBBox();
if (ddx < 0) {
ddx = 0;
} else if (ddx > width - thisBox.width) {
ddx = width - thisBox.width;
}
return ddx;
}
getY(rect, ddy) {
var height = rect.paper.height,
thisBox = rect.getBBox();
if (ddy < 0) {
ddy = 0;
} else if (ddy > height - thisBox.height) {
ddy = height - thisBox.height;
}
return ddy;
}
getWidth(rect, ddw) {
var width = rect.paper.width,
thisBox = rect.getBBox();
if (ddw < 45) {
ddw = 45;
} else if (ddw > width - thisBox.x) {
ddw = width - thisBox.x;
}
return ddw;
}
getHeight(rect, ddh) {
var height = rect.paper.height,
thisBox = rect.getBBox();
if (ddh < 45) {
ddh = 45;
} else if (ddh > height - thisBox.y) {
ddh = height - thisBox.y;
}
return ddh;
}
/**
* RAPHAEL EVENT(s)
* */
dragStart() {
this.ox = this.attr('x');
this.oy = this.attr('y');
this.ow = this.attr('width');
this.oh = this.attr('height');
this.dragging = true;
}
dragMove(dx, dy) {
var ddx = this.ox + dx;
var ddy = this.oy + dy;
switch (this.attr('cursor')) {
case 'nw-resize':
this.attr({
x: getX(this, ddx),
y: getY(this, ddy),
width: getWidth(this, this.ow - dx),
height: getHeight(this, this.oh - dy)
});
break;
case 'ne-resize':
this.attr({
y: getY(this, ddy),
width: getWidth(this, this.ow + dx),
height: getHeight(this, this.oh - dy)
});
break;
case 'se-resize':
this.attr({
width: getWidth(this, this.ow + dx),
height: getHeight(this, this.oh + dy)
});
break;
case 'sw-resize':
this.attr({
x: getX(this, ddx),
width: getWidth(this, this.ow - dx),
height: getHeight(this, this.oh + dy)
});
break;
case 'w-resize':
this.attr({
x: getX(this, ddx, this.ow - dx),
width: getWidth(this, this.ow - dx)
});
break;
case 'e-resize':
this.attr({
width: getWidth(this, this.ow + dx)
});
break;
case 's-resize':
this.attr({
height: getHeight(this, this.oh + dy)
});
break;
case 'n-resize':
this.attr({
y: getY(this, ddy),
height: getHeight(this, this.oh - dy)
});
break;
default:
this.attr({
x: getX(this, ddx),
y: getY(this, ddy)
});
break;
}
}
dragEnd(e) {
this.dragging = false;
}
changeCursor(e, mouseX, mouseY) {
if (this.dragging === true) {
return;
}
var relativeX = mouseX - ($('#paper').offset().left) - this.attr('x');
var relativeY = mouseY - ($('#paper').offset().top) - this.attr('y');
var shapeWidth = this.attr('width');
var shapeHeight = this.attr('height');
var resizeBorder = 10;
if (relativeX < resizeBorder && relativeY < resizeBorder) {
this.attr('cursor', 'nw-resize');
} else if (relativeX > shapeWidth - resizeBorder && relativeY < resizeBorder) {
this.attr('cursor', 'ne-resize');
} else if (relativeX > shapeWidth - resizeBorder && relativeY > shapeHeight - resizeBorder) {
this.attr('cursor', 'se-resize');
} else if (relativeX < resizeBorder && relativeY > shapeHeight - resizeBorder) {
this.attr('cursor', 'sw-resize');
} else if (relativeX < resizeBorder && relativeY < shapeHeight - resizeBorder) {
this.attr('cursor', 'w-resize');
} else if (relativeX > shapeWidth - resizeBorder && relativeY < shapeHeight - resizeBorder) {
this.attr('cursor', 'e-resize');
} else if (relativeX > resizeBorder && relativeY > shapeHeight - resizeBorder) {
this.attr('cursor', 's-resize');
} else if (relativeX > resizeBorder && relativeY < resizeBorder) {
this.attr('cursor', 'n-resize');
} else {
this.attr('cursor', 'move');
}
}
This works pretty good but I have changed the events a little because of jumping and shifting of objects.
var dragStart = function() {
this.ox = this.attr('x');
this.oy = this.attr('y');
this.ow = this.attr('width');
this.oh = this.attr('height');
this.dragging = true;
};
var dragMove = function(dx, dy) {
if (this.state === 'movable') {
this.attr({ x: this.ox + dx, y: this.oy + dy });
}
else {
switch (this.attr('cursor')) {
case 'nw-resize':
this.attr({
x: this.ox + dx,
y: this.oy + dy,
width: this.ow - dx,
height: this.oh - dy
});
break;
case 'n-resize':
this.attr({
y: this.oy + dy,
height: this.oh - dy
});
break;
case 'ne-resize':
this.attr({
y: this.oy + dy,
width: this.ow + dx,
height: this.oh - dy
});
break;
case 'w-resize':
this.attr({
x: this.ox + dx,
width: this.ow - dx
});
break;
case 'e-resize':
this.attr({
width: this.ow + dx
});
break;
case 'sw-resize':
this.attr({
x: this.ox + dx,
width: this.ow - dx,
height: this.oh + dy
});
break;
case 's-resize':
this.attr({
height: this.oh + dy
});
break;
case 'se-resize':
this.attr({
width: this.ow + dx,
height: this.oh + dy
});
break;
default:
this.attr({
x: this.ox + dx,
y: this.oy + dy
});
break;
}
}
};
var changeCursor = function(e, mouseX, mouseY) {
if (this.dragging) {
return;
}
var side = sideDection(e, this);
// if the user's mouse is along the edge we want resize
if (side) {
this.state = 'resizable';
}
// else it's towards the middle and we want to move
else {
this.state = 'movable';
}
var cursor = (side) ? side + '-resize' : 'move';
this.attr('cursor', cursor);
};
var sideDection = function(event, ct) {
var ctFactor = 2;
var directions = {
n: Math.abs(event.offsetY - ct.attr('y')) <= ctFactor,
s: Math.abs(event.offsetY - (ct.attr('height') + ct.attr('y'))) <= ctFactor,
e: Math.abs(event.offsetX - (ct.attr('width') + ct.attr('x'))) <= ctFactor,
w: Math.abs(event.offsetX - ct.attr('x')) <= ctFactor
},side = '';
for (var key in directions) { // loop through all 4 sides and concate the ones that are true
if (directions.hasOwnProperty(key)) {
if (directions[key]) {
side = side + key;
}
}
}
return side;
};
Thanks again!
Linda Rawson
http://www.sensorytech.net