Можно ли сделать элементы SVG выбираемыми в браузере? - PullRequest
0 голосов
/ 25 июня 2019

Я пытаюсь написать графический редактор сетки, и я искал возможность использовать SVG для рисования сетки, в надежде, что есть выбор элементов сетки.Таким образом, сетка SVG будет состоять из цветных прямоугольников, расположенных в столбцах и строках.Пользователь может рисовать цифровые картинки, раскрашивая разные прямоугольники разными цветами.

Я могу легко нарисовать сетку из SVG Rects, и отображение в порядке.Но я хочу, чтобы пользователь мог выбрать набор rects на дисплее SVG.Так что, возможно, они хотят выбрать несколько линий, перетаскивая прямоугольную область мышью и выбирая их, тогда они могут захотеть закрасить все определенным цветом.

Есть ли способ для браузера показать выбор подмножества ритов, отображаемых в моей сетке?Или это не возможно с SVG?Я новичок в SVG, поэтому никогда не работал с ним раньше.Мой простой тест сетки не показывает никакого выделения при перетаскивании мышью по элементам svg rect.

Есть ли простой способ сделать это?

В качестве альтернативы, я думаю, мне нужно было бы использовать холст HTML 5 для отображения и обрабатывать все события мыши самостоятельно.

1 Ответ

0 голосов
/ 25 июня 2019

Вот как бы я это сделал:

  1. Я создаю сетку и сохраняю ректы в массиве rects.

  2. При нажатии мыши я изменяю значение переменных min_x и min_y.

  3. При наведении мыши я изменяю значения max_x и max_y и фильтрую массив rects, чтобы изменить цвет кантов в выбранном диапазоне:

         x >= min_x-size &&
         y >= min_y-size &&
         x <= max_x &&
         y <= max_y
    

Это пример. Пожалуйста, нажмите и перетащите поверх svg canvas.

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...