AFF*_*AFF 1 browser svg selection
我正在尝试编写一个图形网格编辑器,并且正在研究使用 SVG 绘制网格的可能性,希望有一些可以选择网格元素。因此,SVG 网格将由按列和行排列的彩色矩形组成。用户可以通过给不同的矩形涂上不同的颜色来绘制数字图片。
我可以轻松绘制 svg 矩形网格,并且显示效果很好。但我希望用户能够从 svg 显示中选择一组矩形。因此,也许他们想要通过用鼠标拖动矩形区域并选择它们来选择多个矩形,然后他们可能想要为所有特定颜色着色。
有没有办法让浏览器显示对网格中显示的矩形子集的选择?或者说 SVG 不可能做到这一点?我是 SVG 新手,所以以前从未使用过它。我的简单网格测试,用鼠标拖动 svg 矩形元素时不显示任何选择。
有一些简单的方法可以做到这一点吗?
或者,我认为我需要使用 HTML 5 画布来显示并自己处理所有鼠标事件。
我就是这样做的:
我创建网格并将矩形保存在rects数组中。
min_x按下鼠标时,我更改和变量的值min_y。
max_x鼠标松开时,我更改和的值max_y,并过滤rects数组以更改所选范围内矩形的颜色:
x >= min_x-size &&
y >= min_y-size &&
x <= max_x &&
y <= max_y
Run Code Online (Sandbox Code Playgroud)这是一个例子。请在 svg 画布上单击并拖动。
x >= min_x-size &&
y >= min_y-size &&
x <= max_x &&
y <= max_y
Run Code Online (Sandbox Code Playgroud)
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;
}Run Code Online (Sandbox Code Playgroud)
svg{border:1px solid; width:90vh;}
rect{stroke:black; vector-effect:non-scaling-stroke;pointer-events:all}Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1791 次 |
| 最近记录: |