let SVG_NS = svg.namespaceURI;
let size = 10;// the size of a grid cell
let w = 100;//the width of the grid
let h = 100;//the height of the grid
let rectx=0,recty=0;
let selecting = false;
// the rects array
let rects = [];
//create the grid.Push the new rect into the rects array. All the recta have a fill attribute
for(let y = 0; y< h; y+=size){
for(let x = 0; x < w; x+=size){
let rect = drawSVGelmt({x:x,y:y,width:size,height:size,fill:"white"},"rect", svgG);
rects.push(rect)
}
}
let min_x = 0,max_x=100,min_y=0,max_y = 100
//on mouse down change the value of the min_x and min_y
svg.addEventListener("mousedown",(e)=>{
selecting = true
m = oMousePosSVG(e,svg)
min_x = m.x,min_y=m.y;
rectx = m.x;
recty = m.y;
selector.setAttributeNS(null,"x",rectx);
selector.setAttributeNS(null,"y",recty);
})
//on mouse up change the value of the max_x and max_y, filter the rects array and change the color of the "selected" rects
svg.addEventListener("mousemove",(e)=>{
if(selecting){
m = oMousePosSVG(e,svg);
selector.setAttributeNS(null,"width",m.x-rectx);
selector.setAttributeNS(null,"height",m.y-recty);
}
});
svg.addEventListener("mouseup",(e)=>{
if(selecting){
let m = oMousePosSVG(e,svg)
max_x = m.x,max_y=m.y;
selector.setAttributeNS(null,"x",0);
selector.setAttributeNS(null,"y",0);
selector.setAttributeNS(null,"width",0);
selector.setAttributeNS(null,"height",0);
rects.filter((el)=> {
let x = el.getAttribute("x");
let y = el.getAttribute("y");
if (x >= min_x-size &&
y >= min_y-size &&
x <= max_x &&
y <= max_y){
el.setAttribute("fill","red")}
});
}
selecting = false;
})
// a function to draw a new svg element
function drawSVGelmt(o,tag, parent) {
let elmt = document.createElementNS(SVG_NS, tag);
for (let name in o) {
if (o.hasOwnProperty(name)) {
elmt.setAttributeNS(null, name, o[name]);
}
}
parent.appendChild(elmt);
return elmt;
}
// a function to detect the mouse position on the svg canvas
function oMousePosSVG(e, svg) {
var p = svg.createSVGPoint();
p.x = e.clientX;
p.y = e.clientY;
var ctm = svg.getScreenCTM().inverse();
var p = p.matrixTransform(ctm);
return p;
}
svg{border:1px solid; width:90vh;}
rect{stroke:black; vector-effect:non-scaling-stroke;pointer-events:all}
<svg id="svg" viewBox="0 0 100 100">
<g id="svgG"></g>
<rect id="selector" stroke="#ccc" fill="rgba(0,0,0,.2)" />
</svg>