JSFiddle - React, Tailwind, and code Playground

by Avi Algaly

HTML

<div id='container' class='visuals-container'>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div class='visual'></div>
    <div...

CSS

#container {
    border: 1px solid red;
    background-color: #edd;
    width: 500px;
    height: 500px;    
}

.visual, .visual-big {
    border: 1px solid blue;
    background-color: #dde;
    width: 55px;
    height: 55px;
    float: left;
    margin-left: 5px;
    margin-top: 5px;
}
.visual-big {
    width: 100px;
    height: 100px;
    background-color: #ded;
    border: 1px solid green;
}

JavaScript

var container = $('#container');
var visualBig = container.find('.visual-big');
var draggingVisual = false;
visualBig.hide();
container.css('position', 'absolute');
visualBig.css('position', 'absolute');
    
container.on('mousedown', function(e) {
    console.log(e.type + ', target: ' + $(e.target).attr('class'));
    var container = $(this);
    var dragElement = $(e.target);
    draggingVisual = false; dragElement.hasClass('visual');
    console.log('dragging visual: ' + draggingVisual);
    var isDragging = true;
    var currentPosition = container.position();
    var deltaX = currentPosition.left - e.pageX;
    var deltaY = currentPosition.top - e.pageY;
    var drag = function(e) {
        //console.log(e.type + ', target: ' + $(e.target).attr('class'));
        if(!isDragging) return;
        
        draggingVisual = dragElement.hasClass('visual');
        
        var newLeft = e.pageX + deltaX;
        var newTop = e.pageY + deltaY;
        container.css({
            top: newTop,
            left: newLeft
        });
        
        e.stopPropagation();
        e.preventDefault();
        return false;
    };
    var unset = function(e) {
        console.log(e.type + ', target: ' + $(e.target).attr('class'));
        isDragging = false;
        container.off('mousemove', drag);
        container.off('mouseup mouseleave', unset);
    };
    console.log('deltaX: ' + deltaX + ', deltaY: ' + deltaY);
    
    container.on('mouseup mouseleave', unset);
    container.on('mousemove', drag);
    
    e.stopPropagation();
        e.preventDefault();
        return false;
});
container.on('click', '.visual', function(e) {
    console.log(e.type + ', target: ' + $(e.target).attr('class'));

    if(draggingVisual) {
        console.log('dragging visual');
    } else {
        //zoomVisual
        var visual = $(e.target);
        var visualPosition = visual.position();
        var deltaY = (visualBig.height() - visual.height()) / 2;
        var deltaX =...