【问题标题】:raphael.js - custom attributesraphael.js - 自定义属性
【发布时间】:2011-10-01 09:50:43
【问题描述】:

是否可以为 raphael 元素定义自定义属性?

例如

r.circle(25,50,10).attr({fill:'#b71e16', stroke:'#71140f', 'my_custom_attribute':'a value'});

我需要这个的原因是我想在一组元素上做一些非常复杂的动画,我想在某个地方存储每个元素的原始 y 坐标。

【问题讨论】:

    标签: svg raphael


    【解决方案1】:

    是你想要的自定义属性:

    1. 用于记录和检索任意数据的简单存储
    2. 在更改时需要执行自定义操作的属性(例如由 Raphael 的 .attr().animate() 控制的属性)?
    3. 您想在页面/DOM 上的输出 SVG/VML 标记 的属性中强制添加什么? (通常不推荐,但有时需要)

    1。自定义数据存储和检索

    我 99% 确定在 Raphael 中存储任意数据的官方预期方法是使用 .data() 函数,例如

    var circle = r.circle(25,50,10).attr({fill:'#b71e16', stroke:'#71140f'});
    // set it
    circle.data('custom-attribute', 'value');
    
    // get it
    data = circle.data('custom-attribute');
    alert(data);
    

    请注意,从 Raphael 2.1 开始,这适用于元素,不适用于集合。当我需要将数据分配给一个集合时,我倾向于使用for 循环设置它并使用someSet[0].data() 获取它 - 有点杂乱无章,但它可以工作。

    令人讨厌的是,documentation for .data 根本没有说明它的用途(在撰写本文时)......但是 jQuery 中的 .data()、HTML5 中的 data-* 等等都有这个目的,使用它就像这样工作,others on SO talk about it being intended to be used it like this,所以我非常有信心这是将任意数据附加到 Raphael 对象的预期方法。


    2。由attr()animate() 触发的自定义函数

    如果您需要一个行为类似于 Raphael 属性的自定义属性 - 在使用 attranimate(有点像 Raphael 钩子)更改时触发函数或转换 - 这就是 paper.customAttributes 的用途。它定义了一个函数,该函数在为该paper 对象中的任何元素设置命名自定义属性时执行。返回对象应用于元素的标准属性。

    官方文档有一些非常有用的例子,这里有一个改编的:

    // A custom attribute with multiple parameters:
    paper.customAttributes.hsb = function (h, s, b) {
        return {fill: "hsb(" + [h, s, b].join(",") + ")"};
    };
    var c = paper.circle(10, 10, 10);
    // If you want to animate a custom attribute, always set it first - null isNaN
    c.attr({hsb: "0.5 .8 1"});
    c.animate({hsb: [1, 0, 0.5]}, 1e3);
    

    请注意,每个 customAttribute 执行中的 this 是正在为其设置属性的 Raphael 对象。这意味着...


    3。将自定义属性强制添加到浏览器中的 SVG 或 VML 标记中

    Raphael 并不真正支持这一点,所以只有在你真的非常需要时才这样做。但是,如果您确实需要在标记中添加 Raphael 不支持的内容,您可以使用 attranimate 创建一个基本控件来操作它,方法是使用 paper.customAttributes 和 @987654346 @(请注意,element.node 的文档几乎只是非常无用的“Don't mess with it”——你不应该混淆它的原因是,它直接为你提供了 SVG 或 VML 元素,这意味着 Raphael 没有了解您对其所做的任何更改,这可能会使您的 Raphael 对象与其控制的元素不同步,从而可能会破坏某些东西。除非您小心,并使用这样的技术...)。

    这是一个设置 SVG 属性 dy 的示例(假设也使用 jQuery,jQuery 不是必需的但更方便),它允许您控制 Raphael 文本的行距(注意 - 示例代码尚未在 VML/IE 中测试。如果在 VML 模式下不起作用,将更新):

    Live jsfiddle example

    paper.customAttributes.lineHeight = function( value ) {
        // Sets the SVG dy attribute, which Raphael doesn't control
        var selector = Raphael.svg ? 'tspan' : 'v:textpath';
        var $node = $(this.node);
        var $tspans = $node.find(selector);
        $tspans.each(function(){
            // use $(this).attr in jquery v1.6+, fails for SVG in <= v1.5
            // probably won't work in IE
            this.setAttribute('dy', value );
        });
        // change no default Raphael attributes
        return {};
    }
        // Then to use it...
        var text = paper.text(50,50,"This is \n multi-line \n text");
        // If you want to animate a custom attribute, always set it first - null isNaN
        text.attr({lineHeight: 0});
        text.animate({lineHeight: 100},500);
    

    【讨论】:

    • 如何在选择器中访问这些数据?例如 var found = document.querySelectorAll("[transaction='" + current_transaction +"']");
    • @jacktheripper 老实说,我不知道。我从来没有真正成功地弄清楚 data() 数据的存储位置。据我所知,它可能存储为 DOM svg/vml 元素的属性。我通常通过创建大量包含对 Raphael 对象的引用的树层次结构来预测选择需求,从而避免使用选择器。你的问题听起来是个不错的问题——有人可以给出比我更好的答案
    • 还联系了插件的制造商 - 他可能会知道:p
    【解决方案2】:

    我认为你可以做到:

    var circle = r.circle(25,50,10).attr({fill:'#b71e16', stroke:'#71140f'});
    

    然后

    circle["custom-attribute"] = value;
    

    希望这会有所帮助。

    【讨论】:

    • 这可行,但可能不是最佳实践 - 例如Raphael 的未来版本理论上可能会使用相同的命名空间添加新功能,或者循环遍历 Raphael 对象的所有属性。在提供的 Raphael 中使用 .data 函数可能会更好(尽管没有任何线索表明这是它在文档中的用途......)
    【解决方案3】:

    是的,您应该能够执行以下操作:

    .attr({title: value});
    

    当然,title 是您要设置或创建的属性的名称,value 应该是值。当然,有问题的 raphael 元素将是 attr 的接收者。

    【讨论】:

    • 我已经尝试过这种方法,但没有奏效。我认为我仅限于 SVG 规范中定义的属性:(
    • 哦,你想将它添加到实际的 DOM 元素中吗?是的,我不相信你可以用 Raphael 做到这一点,即使是 SVG 允许的属性,如 id。如果您的脚本没有重新加载上述工作在 Javascript 级别。
    猜你喜欢
    • 1970-01-01
    • 2012-04-06
    • 2011-03-27
    • 2011-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    相关资源
    最近更新 更多