gpt4 book ai didi

javascript - SVG 元素的矩形选择(用于 Raphael)

转载 作者:数据小太阳 更新时间:2023-10-29 05:55:29 28 4
gpt4 key购买 nike

我遇到了以下问题,希望有人知道如何帮助我:

我使用 JavaScript 库 Raphael .现在,我想做的是,当我有很多 Raphael SVG 元素时,只需使用“矩形选择”选择更多元素,即通过从图形背景开始拖动鼠标来创建一个选择矩形(我希望我足够清楚), 并移动这个矩形中的元素。

目前,我发现了类似这样的内容(有人从 previous question of mine 发布了它):

var paper = Raphael(0, 0, '100%', '100%');

var circle = paper.circle(75, 75, 50);
var rect = paper.rect(150, 150, 50, 50);

var set = paper.set();

set.push(circle, rect);
set.attr({
fill: 'red',
stroke: 0
});

var ox = 0;
var oy = 0;
var dragging = false;

set.mousedown(function(event) {
ox = event.screenX;
oy = event.screenY;
set.attr({
opacity: .5
});
dragging = true;
});

set.mousemove(function(event) {
if (dragging) {
set.translate(event.screenX - ox, event.screenY - oy);
ox = event.screenX;
oy = event.screenY;
}
});

set.mouseup(function(event) {
dragging = false;
set.attr({
opacity: 1
});
});

此代码可以在 jsfiddle 上执行.但是,如您所见,这会选择所有元素,只需将它们添加到 Raphael 集中即可。

现在,我认为我的问题将通过以下方式解决:

  1. 选择一个矩形
  2. 将矩形中的节点添加到拉斐尔集
  3. 仅移动选定的项目(即仅移动拉斐尔集合中使用 set.mousemove 的项目)

我现在的问题是前两个问题。

有什么办法吗?

提前致谢!

最佳答案

有趣的问题。为此,您可以在所有其他对象后面放置一个 Canvas 大小的矩形“垫子”,并为其附加拖动事件以选择其他元素。 (请注意,此解决方案使用较新版本的 Raphael,2.1.0:

var paper = Raphael(0, 0, '100%', '100%');

//make an object in the background on which to attach drag events
var mat = paper.rect(0, 0, paper.width, paper.height).attr("fill", "#FFF");

var circle = paper.circle(75, 75, 50);
var rect = paper.rect(150, 150, 50, 50);
var set = paper.set();

set.push(circle, rect);
set.attr({
fill: 'red',
stroke: 0
});
//the box we're going to draw to track the selection
var box;
//set that will receive the selected items
var selections = paper.set();

现在,我们添加一个拖动事件——类似于鼠标悬停事件但具有三个函数 (see documentation),并绘制一个框来跟踪选择空间:

//DRAG FUNCTIONS
//when mouse goes down over background, start drawing selection box
function dragstart (x, y, event) {
box = paper.rect(x, y, 0, 0).attr("stroke", "#9999FF");
}

// When mouse moves during drag, adjust box.
// If the drag is to the left or above original point,
// you have to translate the whole box and invert the dx
// or dy values since .rect() doesn't take negative width or height
function dragmove (dx, dy, x, y, event) {
var xoffset = 0,
yoffset = 0;
if (dx < 0) {
xoffset = dx;
dx = -1 * dx;
}
if (dy < 0) {
yoffset = dy;
dy = -1 * dy;
}
box.transform("T" + xoffset + "," + yoffset);
box.attr("width", dx);
box.attr("height", dy);
}

function dragend (event) {
//get the bounds of the selections
var bounds = box.getBBox();
box.remove();
reset();
console.log(bounds);
for (var c in set.items) {
// Here, we want to get the x,y vales of each object
// regardless of what sort of shape it is.
// But rect uses rx and ry, circle uses cx and cy, etc
// So we'll see if the bounding boxes intercept instead

var mybounds = set[c].getBBox();
//do bounding boxes overlap?
//is one of this object's x extremes between the selection's xe xtremes?
if (mybounds.x >= bounds.x && mybounds.x <= bounds.x2 || mybounds.x2 >= bounds.x && mybounds.x2 <= bounds.x2) {
//same for y
if (mybounds.y >= bounds.y && mybounds.y <= bounds.y2 || mybounds.y2 >= bounds.y && mybounds.y2 <= bounds.y2) {
selections.push(set[c]);
}
}
selections.attr("opacity", 0.5);
}
}

function reset () {
//empty selections and reset opacity;
selections = paper.set();
set.attr("opacity", 1);
}

mat.drag(dragmove, dragstart, dragend);
mat.click(function(e) {
reset();
});

就这样,您有一个新的集合(选择),其中包含通过鼠标拖动选择的每个对象。然后,您可以将鼠标悬停事件从原始事件应用到该集合。

请注意,如果您用选择框划出边界框的 Angular ,这将选择圆形对象,即使它不与圆形区域重叠。如果这是一个问题,你可以为圆圈做一个特例。

jsFiddle

关于javascript - SVG 元素的矩形选择(用于 Raphael),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14708880/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com