草庐IT

javascript - 拉斐尔中多条路径的相同悬停功能

coder 2024-07-28 原文

所以我有了我的 Canvas 和我的路径:

var paper1 = Raphael(10, 50, 960, 560);

var mapShape1 = paper1.path("M339.098,175.503c0,0-55.555,58.823-16.34,75.163s227.451,49.02,227.451,49.02s67.321-25.49,47.713-50.98s-71.896-78.432-71.896-78.432L339.098,175.503z");
var mapShape2 = paper1.path("M548.902,306.876c0,0-209.15-32.026-228.758-46.405s-27.451-27.451-20.262-42.484s26.797-44.444,26.797-44.444l-41.83-86.928l-76.471,77.125c0,0-25.49,169.935,48.366,171.242s292.157-4.575,292.157-4.575V306.876z");
var mapShape3 = paper1.path("M296.614,86.614l38.562,83.66l194.771-7.843l75.817,81.7c0,0,130.066-84.967,73.203-118.301S503.15,48.706,463.935,51.974S296.614,86.614,296.614,86.614z");

我这样设计它们:(我相信这可以改进,有没有办法一次完成所有路径???)

function style1(shape){
  shape.attr({
            "fill": "#33CCFF",
            "stroke": "000000",
            "stroke-width": "5"
        });
}

style1(mapShape1);
style1(mapShape2);
style1(mapShape3);

但我的问题是如何让单个悬停功能在所有路径上起作用,我知道了:

  mapShape1.hover(
    function(){
      this.animate({
        "fill": "#FF3300"
      }, 500);
    },
    function(){
      this.animate({
        "fill": "#33CCFF"
      }, 500)
    }
   );

但它一次只适用于一种形状,我想做

$(mapShape1, mapShape2, mapShape3).hover(...

但这行不通。我错过了什么?

最佳答案

正如 lib3d 所说,您应该使用 Set .但是,不是使用 forEach 遍历集合内容并应用属性/功能,而是可以在集合本身上添加共享属性/功能,这将把它应用到集合的内容上。稍后会详细介绍,首先看看如何创建集合。

设置处理

有两种方法可以创建集合并向其中添加元素:显式和隐式。

显式

这意味着您自己管理集合,并自己向集合添加元素`

var paper, shapeA, shapeB, shapeC, elementSet;

paper = Raphael(10, 50, 960, 560);
elementSet = paper.set();

shapeA = paper.path("M339.098,175.503c0,0-55.555,58.823-16.34,75.163s227.451,49.02,227.451,49.02s67.321-25.49,47.713-50.98s-71.896-78.432-71.896-78.432L339.098,175.503z");
shapeB = paper.path("M548.902,306.876c0,0-209.15-32.026-228.758-46.405s-27.451-27.451-20.262-42.484s26.797-44.444,26.797-44.444l-41.83-86.928l-76.471,77.125c0,0-25.49,169.935,48.366,171.242s292.157-4.575,292.157-4.575V306.876z");
shapeC = paper.path("M296.614,86.614l38.562,83.66l194.771-7.843l75.817,81.7c0,0,130.066-84.967,73.203-118.301S503.15,48.706,463.935,51.974S296.614,86.614,296.614,86.614z");

// now add A and C to the set, as well as a rectangle
elementSet.push(
    shapeA,
    shapeC,
    paper.rect(10, 10, 10, 10, 2)
);

这样您就可以完全控制什么进入集合,什么不进入集合。

隐式

您还可以在绘制元素时标记起点和终点。在起点和终点之间绘制的任何元素都会添加到集合中。

var paper, shapA, shapeB, shapeC, elementSet;

paper = Raphael(10, 50, 960, 560);

paper.setStart();

shapeA = paper.path("M339.098,175.503c0,0-55.555,58.823-16.34,75.163s227.451,49.02,227.451,49.02s67.321-25.49,47.713-50.98s-71.896-78.432-71.896-78.432L339.098,175.503z");
shapeB = paper.path("M548.902,306.876c0,0-209.15-32.026-228.758-46.405s-27.451-27.451-20.262-42.484s26.797-44.444,26.797-44.444l-41.83-86.928l-76.471,77.125c0,0-25.49,169.935,48.366,171.242s292.157-4.575,292.157-4.575V306.876z");
shapeC = paper.path("M296.614,86.614l38.562,83.66l194.771-7.843l75.817,81.7c0,0,130.066-84.967,73.203-118.301S503.15,48.706,463.935,51.974S296.614,86.614,296.614,86.614z");

paper.rect(10, 10, 10, 10, 2);

elementSet = paper.setFinish();

变量 elementSet 现在包含形状 A、B 和 C 以及一个矩形。

显式还是隐式?

我个人建议始终使用显式方法。这样你就可以 100% 控制什么进入你的集合,什么不进入。另外,我发现 setStart() 和 setFinish() 的命名是倒过来的,我们是用“set”“开始”,而不是“设置”“start”。如果您现在了解意图,这可能是显而易见的,但这正是命名不明确的危险 - 下一个开发人员可能不知道并假设不同的东西。

更多用法

对于我们创建的应用程序,我们必须绘制、删除、更新和重新定位复杂的元素组。为了实现这一点,我们大量使用了集合。除了集合允许您将属性应用于集合中的每个元素这一事实外,集合还允许您将其用作 DTO。

例如以下作品:

var elementSet = paper.set();

elementSet.push(elemA, elemB, elemC);
elementSet.myApp.someDTO = {
    property: value,
    something: else
};

为了保持一致性和清晰度,我倾向于使用 myApp 作为 namespace 。 它的美妙之处在于,即使 someDTO 包含 Raphael 元素,您在集合上应用的任何内容都不会应用于 DTO 中的元素。这使得它在您需要时真正可以用来传递上下文、坐标等。

使用集合

现在回到使用集合的好处。让我们在这里回顾您的用例: 您想应用属性并将鼠标悬停在任意数量的路径上。

如果我们像上面的显式示例那样创建一个集合,我们将得到以下结果:

var paper, elementSet;
paper = Raphael(10, 50, 960, 560);
elementSet = paper.set();
elementSet.push(
    paper.path("M339.098,175.503c0,0-55.555,58.823-16.34,75.163s227.451,49.02,227.451,49.02s67.321-25.49,47.713-50.98s-71.896-78.432-71.896-78.432L339.098,175.503z"),
    paper.path("M548.902,306.876c0,0-209.15-32.026-228.758-46.405s-27.451-27.451-20.262-42.484s26.797-44.444,26.797-44.444l-41.83-86.928l-76.471,77.125c0,0-25.49,169.935,48.366,171.242s292.157-4.575,292.157-4.575V306.876z"),
    paper.path("M296.614,86.614l38.562,83.66l194.771-7.843l75.817,81.7c0,0,130.066-84.967,73.203-118.301S503.15,48.706,463.935,51.974S296.614,86.614,296.614,86.614z"),
);

现在在集合上应用样式:

elementSet.attr({
    fill: '#33CCFF',
    stroke: '#000000',
    'stroke-width': 5
});

然后添加悬停:

elementSet.hover(
    function(){
        this.animate({
            "fill": "#FF3300"
        }, 500);
    },
    function(){
        this.animate({
            "fill": "#33CCFF"
        }, 500)
    }
);

集合也像元素一样支持链接:

elementSet.push(
    /* elements */
).attr({
    /* attributes */
}).hover(
    /* hover fn's
);

要查看最终结果,有 a fiddle here

扩展的悬停功能

如果你想将悬停高亮应用到所有元素,你可以再次应用集合上的属性:

onMouseOver: function () {
    elementSet.animate({
        fill: '#FF3300'
    }, 500);
};
onMouseOut: function () {
    elementSet.animate({
        fill: '#33CCFF'
    }, 500);
};

elementSet.hover(onMouseOver, onMouseOut);

可以找到查看此内容的 fiddle here

使用 jQuery

为了能够通过 jQuery 绑定(bind)悬停功能,必须访问 nodes的元素。元素本身不是 DOM 节点,而是 Raphael 对象。通过使用 element.node,可以在该节点上使用 jquery 来添加行为。我个人的经验是这工作得很好,但是你永远不想通过 jquery 修改节点,因为这会导致真正意想不到的行为。 Raphael 提供了您需要的所有功能,不需要使用 jquery。

关于javascript - 拉斐尔中多条路径的相同悬停功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16112830/

有关javascript - 拉斐尔中多条路径的相同悬停功能的更多相关文章

  1. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  2. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  3. ruby-on-rails - Rails - 使用/自定义 URL : '/dashboard' 指定根路径 - 2

    如何使此根路径转到:“/dashboard”而不仅仅是http://example.com?root:to=>'dashboard#index',:constraints=>lambda{|req|!req.session[:user_id].blank?} 最佳答案 您可以通过以下方式实现:root:to=>redirect('/dashboard')match'/dashboard',:to=>"dashboard#index",:constraints=>lambda{|req|!req.session[:user_id].b

  4. ruby-on-rails - 优雅的 Rails : multiple routes, 相同的 Controller Action - 2

    让多条路线去同一条路的最优雅的方式是什么ControllerAction?我有:get'dashboard',to:'dashboard#index'get'dashboard/pending',to:'dashboard#index'get'dashboard/live',to:'dashboard#index'get'dashboard/sold',to:'dashboard#index'这很丑陋。有什么“更优雅”的建议吗?一个类轮的奖励积分。 最佳答案 为什么不只有一个路由和一个Controller操作,并根据传递给它的参数来

  5. ruby-on-rails - 在 RSpec 中,如何以任意顺序期望具有不同参数的多条消息? - 2

    RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)

  6. ruby - 如何根据长度将路径数组转换为嵌套数组或散列 - 2

    我需要根据字符串路径的长度将字符串路径数组转换为符号、哈希和数组的数组给定以下数组:array=["info","services","about/company","about/history/part1","about/history/part2"]我想生成以下输出,对不同级别进行分组,根据级别的结构混合使用符号和对象。产生以下输出:[:info,:services,about:[:company,history:[:part1,:part2]]]#altsyntax[:info,:services,{:about=>[:company,{:history=>[:part1,:pa

  7. ruby-on-rails - 在 Rails 中更高效地查找或创建多条记录 - 2

    我有一个应用需要发送用户事件邀请。当用户邀请friend(用户)参加事件时,如果尚不存在将用户连接到该事件的新记录,则会创建该记录。我的模型由用户、事件和events_user组成。classEventdefinvite(user_id,*args)user_id.eachdo|u|e=EventsUser.find_or_create_by_event_id_and_user_id(self.id,u)e.save!endendend用法Event.first.invite([1,2,3])我不认为以上是完成我的任务的最有效方法。我设想了一种方法,例如Model.find_or_cr

  8. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  9. ruby-on-rails - 如何播种图像的路径? - 2

    Organization和Image具有一对一的关系。Image有一个名为filename的列,它存储文件的路径。我在Assets管道中包含这样一个文件:app/assets/other/image.jpg。播种时如何包含此文件的路径?我已经在我的种子文件中尝试过:@organization=...@organization.image.create!(filename:File.open('app/assets/other/image.jpg'))#Ialsotried:#@organization.image.create!(filename:'app/assets/other/i

  10. ruby-on-rails - rails 功能测试 - 2

    在Rails自动生成的功能测试(test/functional/products_controller_test.rb)中,我看到以下代码:classProductsControllerTest我的问题是:方法调用products()在哪里/如何定义?products(:one)到底是什么意思?看代码,大概意思是“创建一个产品”,但是它是如何工作的呢?注意我是Ruby/Rails的新手,如果这些是微不足道的问题,我深表歉意。 最佳答案 如果您查看test/fixtures文件夹,您会看到一个products.yml文件。这是在您创建

随机推荐