JSFiddle - React, Tailwind, and code Playground
HTML
<body ng-app="contentEditor">
<div>This button creates a box (div) that is draggable and resizable.<br/>
There is a weird behavior while resizing up or left because of JSFiddle.<br/>
This example refers to the CodeReview question <a target="_blanck" href="http://codereview.stackexchange.com/questions/61847/draggable-resizeable-box"><strong>here</strong></a>.</div>
<button ce-box-creator>Click me</button>
</body>
CSS
.contentEditorBox {
border: 1px solid black;
background-color: white;
width: 50px;
height: 50px; }
.draggable {
position: absolute;
top: 2px;
left: 2px;
width: calc(100% - 4px);
height: calc(100% - 4px);
cursor: pointer; }
.n-resize {
position: absolute;
top: -3px;
left: 0px;
width: 100%;
height: 5px;
cursor: n-resize; }
.e-resize {
position: absolute;
top: 0px;
left: calc(100% - 2px);
width: 5px;
height: 100%;
cursor: w-resize; }
.s-resize {
position: absolute;
top: calc(100% - 2px);
left: 0px;
width: 100%;
height: 5px;
cursor: s-resize; }
.w-resize {
position: absolute;
top: 0px;
left: -3px;
width: 5px;
height: 100%;
cursor: e-resize; }
.nw-resize {
position: absolute;
top: -3px;
left: -3px;
width: 7px;
height: 7px;
cursor: nw-resize; }
.ne-resize {
position: absolute;
top: -3px;
left: calc(100% - 4px);
width: 7px;
height: 7px;
cursor: ne-resize; }
.se-resize {
position: absolute;
top: calc(100% - 4px);
left: calc(100% - 4px);
width: 7px;
height: 7px;
cursor: se-resize; }
.sw-resize {
position: absolute;
top: calc(100% - 4px);
left: -3px;
width: 7px;
height: 7px;
cursor: sw-resize; }
JavaScript
(function() {
var contentEditor = angular.module("contentEditor", []);
// To create a empty resizable and draggable box
contentEditor.directive("ceBoxCreator", function($document, $compile) {
return {
restrict: 'A',
link: function($scope, $element, $attrs) {
$element.on("mousedown", function($event) {
var newNode = $compile('<div class="contentEditorBox" ce-drag ce-resize></div>')($scope);
newNode.css({
position: "absolute",
top: $event.pageY - 25 + "px",
left: $event.pageX - 25 + "px",
});
angular.element($document[0].body).append(newNode);
});
}
}
});
// To manage the drag
contentEditor.directive("ceDrag", function($document) {
return function($scope, $element, $attr) {
var startX = 0, startY = 0;
var newElement = angular.element('<div class="draggable"></div>');
$element.append(newElement);
newElement.on("mousedown", function($event) {
event.preventDefault();
// To keep the last selected box in front
angular.element(document.querySelectorAll(".contentEditorBox")).css("z-index", "0");
$element.css("z-index", "1");
startX = $event.pageX - $element[0].offsetLeft;
startY = $event.pageY - $element[0].offsetTop;
$document.on("mousemove", mousemove);
$document.on("mouseup", mouseup);
});
function mousemove($event) {
y = $event.pageY - startY;
x = $event.pageX - startX;
$element.css({
top: y + "px",
left: x + "px"
});
}
function mouseup() {
$document.off("mousemove", mousemove);
$document.off("mouseup", mouseup);
}
};
});
// To manage the resize
contentEditor.directive("ceResize", function($document) {
return function($scope, $element, $attr) {
//...