JSFiddle - React, Tailwind, and code Playground
by mamounothman
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.15.0/d3.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/interactjs@latest/dist/interact.min.js"></script>
CSS
svg {
width: 100%;
height: 100%;
background-color: #2e9;
-ms-touch-action: none;
touch-action: none;
}
body { margin: 0; }
JavaScript
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 300);
var g = svg.append('g')
.attr('class', 'the_group');
g.append('rect')
.attr('stroke', 'blue')
.attr('x', 20)
.attr('y', 20)
.attr("width", 120)
.attr("height", 120)
.attr('stroke-width', 2)
.attr('stroke', 'white')
.attr('fill', 'grey');
g.append('text')
.attr('x', 30)
.attr('y', 50)
.text('Some text');
var dx = 0, dy = 0;
interact('.the_group')
.resizable({
edges: {
left: true,
right: true,
bottom: true,
top: true
}
})
.draggable({
modifiers: [
interact.modifiers.restrict({
restriction: 'svg',
endOnly: true
})
]
})
/* .on('resizestart', function(event) {
dx = (parseFloat(event.target.getAttribute('dx')) || 0);
dy = (parseFloat(event.target.getAttribute('dy')) || 0);
}) */
.on('resizemove', function(event) {
var target = event.target;
var rect = target.childNodes[0];
var text = target.childNodes[1];
dx = (parseFloat(event.target.getAttribute('dx')) || 0);
dy = (parseFloat(event.target.getAttribute('dy')) || 0);
if (event.deltaRect.left != 0 || event.deltaRect.right != 0)
rect.setAttribute('width', event.rect.width + 'px');
if (event.deltaRect.top != 0 || event.deltaRect.bottom != 0)
rect.setAttribute('height', event.rect.height + 'px');
// the user may move the top/left borders
dx += event.deltaRect.left;
dy += event.deltaRect.top;
rect.setAttribute('transform',
'translate(' + dx + ', ' + dy + ')')
event.target.setAttribute('dx', dx);
event.target.setAttribute('dy', dy);
})
/* .on('dragstart', function(event) {
dx = (parseFloat(event.target.getAttribute('dx')) || 0);
dy = (parseFloat(event.target.getAttribute('dy')) || 0);
}) */
.on('dragmove',...