JSFiddle - React, Tailwind, and code Playground
by joshmoto
HTML
<div class="area">
<img src="https://dragonballsuper-france.fr/wp-content/uploads/2017/10/DIHQF2OXoAAJi4n-660x330.jpg" alt="" />
<div class="rect">
<div class="exclusion-x"></div>
<div class="exclusion-y"></div>
</div>
</div>
CSS
/* area div */
.area {
overflow: hidden;
position: relative;
margin-bottom: 8px;
}
/* area div hover cursor */
.area:hover {
cursor: crosshair;
}
/* img tag in area div */
.area IMG {
display: block;
width: 100%;
pointer-events: none;
user-select: none;
}
/* rectangle div in area div */
.area .rect {
opacity: 0;
transition: all 0s ease;
position: absolute;
border: 1px solid red;
z-index: 1;
pointer-events: none;
user-select: none;
}
/* rectangle div css when in draw or drawn mode */
.area.draw .rect,
.area.drawn .rect {
opacity: 1;
pointer-events: initial;
user-select: initial;
}
/* below css is for fun rendering outer exclusion area of drawn rectangle div with a opaque overlay */
/* rectange exclusing pseudo elems base css */
.area.drawn .rect .exclusion-x::before,
.area.drawn .rect .exclusion-x::after,
.area.drawn .rect .exclusion-y::before,
.area.drawn .rect .exclusion-y::after {
position: absolute;
content: '';
display: block;
background: #000;
opacity: .75;
z-index: -1;
pointer-events: none;
user-select: none;
}
/* rectange outer opaque x above css */
.area.drawn .rect .exclusion-x::before {
bottom: calc(100% + 1px);
left: 50%;
transform: translateX(-50%);
height: 200vh;
width: 200vw;
}
/* rectange outer opaque x below css */
.area.drawn .rect .exclusion-x::after {
top: calc(100% + 1px);
left: 50%;
transform: translateX(-50%);
height: 200vh;
width: 200vw;
}
/* rectange outer opaque y left css */
.area.drawn .rect .exclusion-y::before {
right: calc(100% + 1px);
top: -1px;
bottom: -1px;
width: 200vw;
}
/* rectange outer opaque y right css */
.area.drawn .rect .exclusion-y::after {
left: calc(100% + 1px);
top: -1px;
bottom: -1px;
width: 200vw;
}
/* below css is for fun hovering and draging the rectangle */
/* rectangle div in area div */
.area .rect:hover {
cursor: move;
}
JavaScript
// our updatable variable objects to use globally
let img = {};
let rect = {};
let position = {};
let drag = {};
let dragPoint = {};
// image matrix function to update img object variable
function imgMatrix() {
// our image object inside area
let $img = $('IMG', '.area');
// offset data of image
let offset = $img.offset();
// add/update object key data
img.width = $img.outerWidth();
img.height = $img.outerHeight();
img.offsetX = offset.left - $(document).scrollLeft();
img.offsetY = offset.top - $(document).scrollTop();
}
// position matrix function to update position object variable
function positionMatrix(e, type = false) {
// if mousedown param is true... for use in
if (type === 'mousemove') {
// set the top/left position object data with percentage position
drag.top = (100 / img.height) * ((e.pageY - $(document).scrollTop()) - img.offsetY);
drag.right = 100 - ((100 / img.width) * ((e.pageX - $(document).scrollLeft()) - img.offsetX));
drag.bottom = 100 - ((100 / img.height) * ((e.pageY - $(document).scrollTop()) - img.offsetY));
drag.left = (100 / img.width) * ((e.pageX - $(document).scrollLeft()) - img.offsetX);
position.top = drag.top - dragPoint.top;
position.left = drag.left - dragPoint.left;
position.bottom = drag.bottom - dragPoint.bottom;
position.right = drag.right - dragPoint.right;
//console.log(position);
} else {
// if mousedown param is true... for use in
if (type === 'mousedown') {
// set the top/left position object data with percentage position
position.top = (100 / img.height) * ((e.pageY - $(document).scrollTop()) - img.offsetY);
position.left = (100 / img.width) * ((e.pageX - $(document).scrollLeft()) - img.offsetX);
}
// set the right/bottom position object data with percentage position
position.right = 100 - ((100 / img.width) * ((e.pageX - $(document).scrollLeft()) - img.offsetX));
position.bottom = 100 - ((100 /...