Drag/resize/rotate
Touch-enabled dragging, resizing, rotating
by nichollascarter
HTML
<script src="https://rawgit.com/nichollascarter/js-drag-resize-rotate-tool/master/dist/js/subjx.js"></script>
<link rel="stylesheet" href="https://rawgit.com/nichollascarter/js-drag-resize-rotate-tool/master/dist/style/subjx.css">
<div style="width:100%; height:100%;">
<div style="position: absolute; display: inline; box-sizing: border-box; color: black">
Double click on element to activate/deactivate
<div id="move">
Move:
<span></span>
</div>
<div id="resize">
Resize:
<span></span>
</div>
<div id="rotate">
Rotate:
<span></span>
</div>
</div>
<svg id="svg-container" width="100%" height="50%" transform="scale(1, 1)">
<rect class="drag-svg" x="552" y="209" width="30" height="30" stroke="black" fill="transparent" stroke-width="5" transform="rotate(0 567 224)"></rect>
<rect class="drag-svg" x="469" y="211" rx="10" ry="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5" transform="rotate(0 484 226)"></rect>
<circle cx="792" cy="152" r="20" stroke="red" fill="transparent" stroke-width="5" transform="rotate(0 792 152)"></circle>
<ellipse class="drag-svg" cx="358" cy="222" rx="22.000000000000004" ry="17" stroke="red" fill="transparent" stroke-width="5" transform="rotate(0 358 222)"></ellipse>
<line class="drag-svg" x1="626" x2="666" y1="200" y2="240" stroke="orange" fill="transparent" stroke-width="5" transform="rotate(0 646 220)"></line>
<polyline class="drag-svg" points="599 73 604 83 609 78 614 93 619 88 624 103 629 98 634 113 639 108" stroke="orange" fill="transparent" stroke-width="5" transform="rotate(0 619 93)"></polyline>
<polygon class="drag-svg" points="356 71 361 91 376 91 366 101 371 116 356 106 341 116 346 101 336 91 351 91" stroke="green" fill="transparent" stroke-width="5" transform="rotate(0 356 93.5)"></polygon>
<path class="drag-svg" d="M451,91 Q471,66,481,91 T521,91 " fill="none" stroke="blue" stroke-width="5"...
CSS
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
.draggable {
position: absolute;
width: 150px;
height: 50px;
background-color: yellow;
}
.clonable {
position: absolute;
width: 50px;
height: 50px;
left: 0;
}
JavaScript
class ZoomContainer {
constructor() {
this.scale = 1;
}
zoom(e) {
e.preventDefault();
if (!e.shiftKey) return;
let {
scale
} = this;
const newScale = scale + (e.wheelDelta < 0 ? -0.25 : 0.25);
scale = newScale > 2 || newScale < 0.5 ? scale : newScale;
subjx(e.currentTarget).css({
transform: `scale(${scale},${scale})`
});
this.scale = scale;
}
}
const zoomSvg = new ZoomContainer(),
zoomHtml = new ZoomContainer();
subjx('#svg-container')
.on('mousewheel', e => {
zoomSvg.zoom(e);
});
subjx('#stack')
.on('mousewheel', e => {
zoomHtml.zoom(e);
});
// define methods
const methods = {
onInit(el) {
console.log('init');
},
onMove({
dx,
dy
}) {
subjx('#move > span')[0].innerHTML = `x: ${dx}px; y: ${dy}px`;
},
onResize({
dx,
dy
}) {
subjx('#resize > span')[0].innerHTML = `x: ${dx}px; y: ${dy}px`;
},
onRotate({
delta
}) {
subjx('#rotate > span')[0].innerHTML = `${Math.floor(delta * 180 / Math.PI)}deg`;
},
onDrop() {
console.log('is dropped');
},
onDestroy() {
console.log('is destroyed');
}
};
// additional options
const svgOptions = {
container: '#svg-container',
//restrict: '#svg-container',
rotationPoint: true,
snap: {
x: 30,
y: 30,
angle: 25
},
...methods
};
const svgs =
subjx('.drag-svg').drag(svgOptions);
subjx(svgs.controls).on('dblclick', () => {
svgs.disable();
});
// double click activating/deactivating the drag method
subjx('.drag-svg').on('dblclick', e => {
if (e.currentTarget.classList.contains('sjx-drag')) return;
const xDraggable = subjx(e.currentTarget).drag(svgOptions);
// adding event to controls
const controls = xDraggable.controls;
subjx(controls).on('dblclick', () => {
xDraggable.disable();
});
});
const options = {
container: '#container',
//restrict: '#stack',
//proportions: true,
each: {
move: true,
resize: true
},
snap: {
x:...