JSFiddle - React, Tailwind, and code Playground

by angry_bender

HTML

<div class='container'>
    <div class='figure' id='fig_1'></div>
    <div class='figure' id='fig_2'></div>
    <div class='figure' id='fig_3'></div>
    <div class='figure' id='fig_4'></div>
    
    <div class='box'></div>
</div>

CSS

.container {
    position: relative;
    width: 500px;
    height: 600px;
    border: 1px solid red;
}

.box {
    position: absolute;
    border: 1px solid green;
    display: none;
    z-index: 1;
}

.figure {
    position: absolute;
    background: #aaa;
    z-index: 5;
}

#fig_1 {
    width: 150px;
    height: 75px;
    left: 10px;
    top: 10px;
}

#fig_2 {
    width: 120px;
    height: 85px;
    left: 100px;
    top: 167px;
}

#fig_3 {
    width: 180px;
    height: 30px;
    left: 300px;
    top: 17px;
}

#fig_4 {
    width: 180px;
    height: 150px;
    left: 140px;
    top: 390px;
}

JavaScript

var Element = function($obj, pull) {
    this.$obj = $obj;
    this.$$pull = pull;
}
Element.prototype.$obj = null;
Element.prototype.$$pull = [];
Element.prototype.isCatch = false;
Element.prototype.x = 0;
Element.prototype.y = 0;
Element.prototype.x0 = 0;
Element.prototype.y0 = 0;
Element.prototype.dx = 0;
Element.prototype.dy = 0;

Element.prototype.minX = 0;
Element.prototype.maxX = 0;
Element.prototype.minY = 0;
Element.prototype.maxY = 0;

Element.prototype.calcBox = function()
{
    var x0 = this.x0;
    var y0 = this.y0;
    
    var x1 = x0 + this.$obj.width();
    var y1 = y0 + this.$obj.height();
    
    var $intr;
    var ix0, iy0, ix1, iy1;
    var minX = 500; // magic, must be container width
    var minY = 600; // magic, must be container height
    var maxX = 0;
    var maxY = 0;
    this.$$pull.each(function() {
        $intr = $(this);
        if ($intr.data('_class').isCatch) continue; // this i am
        
        ix0 = $intr.offset().left;
        iy0 = $intr.offset().top;
        
        ix1 = ix0 + $intr.width();
        iy1 = iy0 + $intr.height();
        
        // left side:
        if (ix1 <= x0 && (iy0 <= y1 && iy0 >= y0 || iy1 <= y1 && iy1 >= y0)) {
            if (ix1 < minX) minX = ix1;
        }
            
    });
    
    $('.box').show();
    $('.box').css('left', minX);
}

Element.prototype.move = function(eventX, eventY) {
    var dx = eventX - this.mx;
    var dy = eventY - this.my;
    
    this.$obj.css('left', this.x0 + dx);
    this.$obj.css('top', this.y0 + dy);
}

$('.figure').each(function() {
    $(this).data('_class', new Element($(this), $('.figure')));
});

$('.figure')
.on('mousedown', function(e) {
    var Element = $(this).data('_class');
    Element.isCatch = true;
    Element.dx = e.pageX - $(this).offset().left;
    Element.dy = e.pageY - $(this).offset().top;
    
    Element.mx = e.pageX;
    Element.my = e.pageY;
    
    Element.x0 = $(this).offset().left;
    Element.y0 = $(this).offset().top;
    
 ...