Raphaël.js - attributs personnalisés

Est-il possible de définir un attribut personnalisé pour un raphaël élément?

Par exemple

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

La raison pour laquelle j'ai besoin de ceci est que je veux faire une animation assez complexe sur un ensemble d'éléments et je veux quelque part stocker la coordonnée y originale pour chacun.

24
demandé sur boz 2011-07-08 19:56:13

3 réponses

Est l'attribut personnalisé que vous souhaitez:

  1. Un magasin simple pour les données arbitraires, à enregistrer et à récupérer?
  2. un attribut où une action personnalisée doit être effectuée quand elle est modifiée (comme les attributs contrôlés avec .attr() et .animate() de Raphaël)?
  3. quelque chose que vous voulez forcer dans les attributs de la sortie SVG / VML markup sur la page / DOM? (pas normalement recommandé, mais parfois nécessaire)

1. Stockage et récupération de données personnalisés

Je suis sûr à 99% que le moyen officiel de stocker des données arbitraires dans Raphael est d'utiliser la fonction .data(), par exemple

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);

Noter que Raphaël 2.1 cela fonctionne pour les éléments, pas ensembles de. Quand j'ai besoin d'assigner des données à un ensemble, j'ai tendance à le définir avec une boucle for et à l'obtenir avec someSet[0].data() - un peu cludge, mais cela fonctionne.

Fâcheusement la documentation pour .data ça ne dit rien rien du tout sur ce que c'est pour (au moment de la rédaction)... mais .data() dans jQuery, data-* en HTML5, etc etc ont tous ce but, en l'utilisant comme cela fonctionne, et d'autres sur SO parlent de ce qu'il est destiné à être utilisé comme ceci, donc je suis assez confiant que c'est la méthode prévue pour attacher des données arbitraires aux objets Raphael.


2. Fonctions personnalisées déclenchées par attr() ou animate()

Si vous avez besoin d'un attribut personnalisé qui se comporte comme des attributs Raphael - déclencher une fonction ou une transformation lorsqu'elle est modifiée en utilisant attr ou animate (un peu comme un crochet Raphael) - c'est ce que paper.customAttributes est pour. Il définit une fonction qui est exécutée chaque fois que l'attr personnalisé nommé est défini pour un élément de cet objet paper. L'objet de retour est appliqué aux attributs standard de l'élément.

Les docs officiels ont quelques exemples assez utiles pour celui-ci, en voici un adapté:

// 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);

Notez que this dans chaque l'exécution customAttribute est l'objet Raphael pour lequel l'attr est défini. Ce moyen...


3. Forcer l'attribut personnalisé dans le balisage SVG ou VML dans le navigateur

Raphael ne supporte pas vraiment cela, alors ne le faites que si vous en avez vraiment, vraiment besoin. Mais si vous avez vraiment besoin de quelque chose dans le balisage que Raphael ne supporte tout simplement pas, vous pouvez créer un contrôle rudimentaire pour le manipuler en utilisant attr et animate en utilisant paper.customAttributes et element.node (notez que la documentation de element.node est à peu près juste le très inutile " Ne pas le salir " - la raison pour laquelle vous ne devriez pas le salir est, il vous donne directement L'élément SVG ou VML, ce qui signifie que Raphael ne connaît aucune des modifications que vous y apportez, ce qui peut désynchroniser votre objet Raphael avec l'élément Sauf si vous faites attention, et utilisez une technique comme celle-ci...).

Voici un exemple (en supposant que jQuery est également utilisé, jQuery n'est pas essentiel mais est plus pratique) qui définit la propriété SVG dy, qui vous permet de contrôler l'espacement des lignes du texte Raphael (note - exemple de code non encore testé dans VML/IE. mise à jour si cela ne fonctionne pas en mode VML):

Vivre jsfiddle exemple

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);
41
répondu user568458 2017-05-23 12:02:04

Je pense que vous pouvez faire:

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

Puis

circle["custom-attribute"] = value;

J'espère que cela aide.

3
répondu alvomenyet 2011-07-19 12:40:33

Oui, vous devriez être capable de faire ce qui suit:

.attr({title: value});

Bien sûr, title est le nom de l'attribut que vous souhaitez définir ou créer et value devrait être la valeur. Bien sûr, l'élément raphael en question serait le récepteur pour attr.

0
répondu LeakyBucket 2011-07-20 17:19:01