JSFiddle - React, Tailwind, and code Playground
by Lazaro Contreras
HTML
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg">
<defs>
<mask id="hole">
<rect width="100%" height="100%" fill="white"/>
<rect class="box" x="0" y="0" width="0" height="0" style="fill:black;stroke:black;stroke-width:0;fill-opacity:1;stroke-opacity:1;stroke-dasharray:25"/>
</mask>
</defs>
<rect class="outer" width="100%" height="100%" fill="rgba(0,0,0,0.6)" mask="url(#hole)"/>
<rect class="box inner" x="0" y="0" width="0" height="0" style="fill:black;stroke:var(--white);stroke-width:2;fill-opacity:0;stroke-opacity:1;stroke-dasharray:25"/>
</svg>
<div class="hit2"></div>
<div class="hit3"></div>
<div class="hit4"></div>
<div class="hit5"></div>
<div class="hit6"></div>
<div class="hit7"></div>
<div class="hit8"></div>
<div class="hit1"></div>
<img height="100%" src="https://cdna.artstation.com/p/assets/images/images/017/604/714/large/travis-m-couch-mountaintopweb.jpg?1556656231">
CSS
.box {
stroke-dasharray: 100;
animation: dash 20s linear infinite;
}
@keyframes dash {
to {
stroke-dashoffset: -1000;
}
}
:root {
--white: rgba(255, 255, 255, 0.8);
}
svg {
position: absolute;
width: 100%;
height: 100%;
}
[class^="hit"]{
top: -10px;
left: -10px;
position: absolute;
width: 10px;
height: 10px;
background: var(--white);
user-select: none;
}
.hit1, .hit2 {
cursor: nwse-resize;
}
.hit3, .hit4 {
cursor: nesw-resize;
}
.hit5, .hit6 {
cursor: ns-resize;
}
.hit7, .hit8 {
cursor: ew-resize;
}
html,
body {
margin: 0;
padding: 0;
background: blue;
}
JavaScript
var boxs = document.querySelectorAll(".box");
var inner = document.querySelector('.inner'),
outer = document.querySelector('.outer');
var hit1 = document.querySelector('.hit1'),
hit2 = document.querySelector('.hit2'),
hit3 = document.querySelector('.hit3'),
hit4 = document.querySelector('.hit4'),
hit5 = document.querySelector('.hit5'),
hit6 = document.querySelector('.hit6'),
hit7 = document.querySelector('.hit7'),
hit8 = document.querySelector('.hit8');
var hits = document.querySelectorAll('[class^="hit"]');
var mouseY = 0, mouseX = 0, element = null, minBox = 0, hitSize = 10;
hits.forEach((h) => {
h.addEventListener('mousedown', function(e) {
mouseY = e.pageY - e.currentTarget.offsetTop;
mouseX = e.pageX - e.currentTarget.offsetLeft;
element = (element == null)? e.currentTarget : element;
window.addEventListener('mousemove', move);
})
});
outer.addEventListener('mousedown', function(e) {
hit1.style.top = e.pageY + 'px'
hit1.style.left = e.pageX + 'px'
hit2.style.top = e.pageY + 'px'
hit2.style.left = e.pageX + 'px'
hit3.style.top = e.pageY + 'px'
hit3.style.left = e.pageX + 'px'
hit4.style.top = e.pageY + 'px'
hit4.style.left = e.pageX + 'px'
hit5.style.top = e.pageY + 'px'
hit5.style.left = e.pageX + 'px'
hit6.style.top = e.pageY + 'px'
hit6.style.left = e.pageX + 'px'
hit7.style.top = e.pageY + 'px'
hit7.style.left = e.pageX + 'px'
hit8.style.top = e.pageY + 'px'
hit8.style.left = e.pageX + 'px'
element = hit1;
window.addEventListener('mousemove', move);
})
window.addEventListener('mouseup', function() {
element = null;
window.removeEventListener('mousemove', move);
});
function move(e) {
if ((e.pageY - mouseY) > 0) {
if (element == hit1 || element == hit3 || element == hit5) {
if (((e.pageY - mouseY) - hit2.offsetTop - hitSize) > minBox) {
hit1.style.top = e.pageY - mouseY + 'px';
hit3.style.top = e.pageY - mouseY +...