JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/interact.js/1.10.11/interact.min.js"></script>
<div id="canvas">
<div class="centerVerticalGuideline"></div>
<div class="centerHorizontalGuideline"></div>
<div class="dragElement"></div>
<div class="dragElement2"></div>
</div>
CSS
#canvas{
position: relative;
width: 770px;
height: 433.13px;
border: 1px solid #ccc;
margin: 0 auto;
overflow: hidden;
margin-bottom: 20px;
background: #fffffc;
}
.dragElement{
position: absolute;
width: 200px;
height: 200px;
background: #4aaee7;
}
.dragElement2{
position: absolute;
width: 100px;
height: 100px;
background: #e74c3c;
}
.centerVerticalGuideline{
border-left: 1px solid;
position: absolute;
width: 0px;
height: 500px;
top: 0;
z-index: 100;
left: 50%;
pointer-events: none;
visibility: hidden;
}
.centerHorizontalGuideline{
border-top: 1px solid;
position: absolute;
width: 100%;
height: 0;
top: 50%;
z-index: 100;
left: 0;
pointer-events: none;
visibility: hidden;
}
JavaScript
let dynamicTargets = [];
interact('div#canvas .dragElement, div#canvas .dragElement2').draggable({
modifiers: [
interact.modifiers.snap({
targets: dynamicTargets,
relativePoints: [{
x: 0,
y: 0
}]
})],
onstart: function(event){
let element = event.target;
let element_width = parseInt(element.offsetWidth);
let element_height = parseInt(element.offsetHeight);
let element_half_width = parseInt(element_width / 2);
let element_half_height = parseInt(element_height / 2);
let x_axis = 395
let y_axis = 228
dynamicTargets.push({x: x_axis, range: 20});
dynamicTargets.push({x: (x_axis - element_half_width), range: 20});
dynamicTargets.push({x: (x_axis - element_width), range: 20});
dynamicTargets.push({y: y_axis, range: 20});
dynamicTargets.push({y: (y_axis - element_half_height), range: 20});
dynamicTargets.push({y: (y_axis - element_height), range: 20});
dynamicTargets.push({x: parseInt(x_axis),y: parseInt(y_axis), range: 40});
},
onmove: function (event) {
let target = event.target;
let x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
let y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
target.style.left = `${x}px`;
target.style.top = `${y}px`;
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
if(Number.isInteger(x)){
document.querySelector('.centerVerticalGuideline').style.visibility = 'visible';
}
if(Number.isInteger(y)){
document.querySelector('.centerHorizontalGuideline').style.visibility = 'visible';
}
},
onend: function(event){
dynamicTargets.length = 0;
...