JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdn.jsdelivr.net/gh/ionstage/jcore@master/jcore.js"></script>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
CSS
.box {
background-color: white;
border: 1px solid #333;
position: absolute;
}
JavaScript
class Box extends jCore.Component {
constructor(el, x, y, width, height) {
super(el);
this.x = this.prop(x);
this.y = this.prop(y);
this.width = this.prop(width);
this.height = this.prop(height);
this.draggable = new BoxDraggable(this);
this.draggable.enable();
this.markDirty();
}
onredraw() {
this.redrawBy('x', 'y', (x, y) => {
this.el.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
});
this.redrawBy('width', width => {
this.el.style.width = width + 'px';
});
this.redrawBy('height', height => {
this.el.style.height = height + 'px';
});
}
}
class BoxDraggable extends jCore.Draggable {
onstart(box, x, y, event, context) {
event.preventDefault();
context.x = box.x();
context.y = box.y();
}
onmove(box, dx, dy, event, context) {
box.x(context.x + dx);
box.y(context.y + dy);
}
}
class BoxRelation extends jCore.Relation {
constructor(parent, child) {
super();
this.parent = parent;
this.child = child;
}
update() {
const p = this.parent;
const c = this.child;
c.x(this.clamp(c.x(), p.x(), p.x() + p.width() - c.width()));
c.y(this.clamp(c.y(), p.y(), p.y() + p.height() - c.height()));
}
clamp(v, low, high) {
return Math.min(Math.max(v, low), high);
}
}
const elements = document.querySelectorAll('.box');
const boxes = {
parent: new Box(elements[0], 0, 0, 300, 300),
child: new Box(elements[1], 30, 30, 200, 200),
grandchild: new Box(elements[2], 60, 60, 100, 100),
};
const relations = {
'parent-child': new BoxRelation(boxes.parent, boxes.child),
'child-grandchild': new BoxRelation(boxes.child, boxes.grandchild),
};
boxes.parent.addRelation(relations['parent-child']);
boxes.child.addRelation(relations['parent-child']);
boxes.child.addRelation(relations['child-grandchild']);
boxes.grandchild.addRelation(relations['child-grandchild']);