JSFiddle - React, Tailwind, and code Playground
HTML
<div id="container">
<div id="selection"></div>
<div class="selectable">A</div>
<div class="selectable">B</div>
<div class="selectable">C</div>
<div class="selectable">D</div>
<div class="selectable">E</div>
<div class="selectable">F</div>
<div class="selectable">G</div>
<div class="selectable">H</div>
</div>
CSS
#container {
margin: 40px;
padding: 10px;
border-style: solid;
}
#selection {
display: none;
position: absolute;
background: lightblue;
border-color: blue;
border-width: 1px;
border-style: solid;
opacity: .5;
}
* {
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor: default;
}
.selectable {
font-size: 3em;
background-color: lightgray;
border-radius: 10px;
display: inline-block;
width: 100px;
line-height: 100px;
margin: 10px;
text-align: center;
}
.selectable.mark {
background-color: yellow;
}
JavaScript
(function() {
var beginX, beginY; // a posição do vértice fixo
var active; // se a seleção está ativa (visível)
var selection = document.getElementById("selection"); // o elemento
var limit = document.getElementById("container").getBoundingClientRect();
window.onmousedown = function (e) {
// se o clique foi fora do limite, não continuar
if (e.clientX > limit.right || e.clientX < limit.left ||
e.clientY > limit.bottom || e.clientY < limit.top) {
return;
}
beginX = e.clientX;
beginY = e.clientY;
active = true;
selection.style.display = "block"; // deixar a div visível
window.onmousemove(e); // forçar a atualização de posição (função abaixo)
};
window.onmousemove = function (e) {
if (active) {
// cx,cy = a posição do segundo vértice
// é a posição do mouse limitada pelo limite
var cx = Math.max(Math.min(e.clientX, limit.right), limit.left);
var cy = Math.max(Math.min(e.clientY, limit.bottom), limit.top);
// x,y,w,h = o retângulo entre os vértices
var x = Math.min(beginX, cx);
var y = Math.min(beginY, cy);
var w = Math.abs(beginX - cx);
var h = Math.abs(beginY - cy);
// aplicar a posição e o tamanho
selection.style.left = x+"px";
selection.style.top = y+"px";
selection.style.width = w+"px";
selection.style.height = h+"px";
// procurar elementos selecionados
var list = document.getElementsByClassName("selectable");
for (var i = 0; i < list.length; ++i) {
var rect = list[i].getBoundingClientRect();
if (rect.bottom > y && rect.top < y+h &&
rect.right > x && rect.left < x+w) {
list[i].classList.add("mark");
...