jjzjj

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

coder 2025-02-24 原文

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

我使用 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/

有关javascript - SVG 元素的矩形选择(用于 Raphael)的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  3. ruby - inverse_of 是否适用于 has_many? - 2

    当我使用has_one时,它​​工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290

  4. ruby - Rails 3 的 RGB 颜色选择器 - 2

    状态:我正在构建一个应用程序,其中需要一个可供用户选择颜色的字段,该字段将包含RGB颜色代码字符串。我已经测试了一个看起来很漂亮但效果不佳的。它是“挑剔的颜色”,并托管在此存储库中:https://github.com/Astorsoft/picky-color.在这里我打开一个关于它的一些问题的问题。问题:请建议我在Rails3应用程序中使用一些颜色选择器。 最佳答案 也许页面上的列表jQueryUIDevelopment:ColorPicker为您提供开箱即用的产品。原因是jQuery现在包含在Rails3应用程序中,因此使用基

  5. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

  6. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  7. ruby - Hanami link_to 助手只呈现最后一个元素 - 2

    我是HanamiWorld的新人。我已经写了这段代码:moduleWeb::Views::HomeclassIndexincludeWeb::ViewincludeHanami::Helpers::HtmlHelperdeftitlehtml.headerdoh1'Testsearchengine',id:'title'hrdiv(id:'test')dolink_to('Home',"/",class:'mnu_orizontal')link_to('About',"/",class:'mnu_orizontal')endendendendend我在模板上调用了title方法。htm

  8. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  9. ruby - 将n维数组的每个元素乘以Ruby中的数字 - 2

    在Ruby中,是否有一种简单的方法可以将n维数组中的每个元素乘以一个数字?这样:[1,2,3,4,5].multiplied_by2==[2,4,6,8,10]和[[1,2,3],[1,2,3]].multiplied_by2==[[2,4,6],[2,4,6]]?(很明显,我编写了multiplied_by函数以区别于*,它似乎连接了数组的多个副本,不幸的是这不是我需要的)。谢谢! 最佳答案 它的长格式等价物是:[1,2,3,4,5].collect{|n|n*2}其实并没有那么复杂。你总是可以使你的multiply_by方法:c

  10. ruby - "undefined method"用于 rails 模型 - 2

    我正在使用带有Rails的Devise,我想添加一个方法“getAllComments”,所以我这样写:classUser在我的Controller中:defdashboard@user=current_user@comments=@user.getAllComments();end当我访问我的url时,我得到了undefinedmethod`getAllComments'for#我做错了什么?谢谢 最佳答案 因为getAllComments是一个类方法,而您正试图将其作为实例方法访问。您要么需要访问它:User.getAllCom

随机推荐