Is it possible to define a custom attribute for a raphael element?
e.g.
r.circle(25,50,10).attr({fill:'#b71e16', stroke:'#71140f', 'my_custom_attribute':'a value'});
Reason I need this is I want to do some quite complex animation on a whole set of elements and I want somewhere to store the original y coordinate for each one.
Is the custom attribute you want:
.attr()and.animate())?1. Custom data storage and retrieval
I’m 99% sure that the official, intended way to store arbitrary data in Raphael is to use the
.data()function, e.g.Note that as of Raphael 2.1 this works for elements, not sets. When I need to assign data to a set I tend to set it with a
forloop and get it withsomeSet[0].data()– a bit of a cludge, but it works.Annoyingly the documentation for
.datadoesn’t say anything at all about what it is for (at time of writing)… but.data()in jQuery,data-*in HTML5, etc etc all have this purpose, using it like this works, and others on SO talk about it being intended to be used it like this, so I’m pretty confident that this is the intended method for attaching arbitrary data to Raphael objects.2. Custom functions triggered by
attr()oranimate()If you need a custom attribute that behaves like Raphael attributes – triggering a function or transformation when changed using
attroranimate(kind of like a Raphael hook) – that’s what paper.customAttributes is for. It defines a function that is executed any time the named custom attr is set for any element in thatpaperobject. The return object is applied to the element’s standard attributes.The offical docs have some pretty useful examples for this one, here’s an adapted one:
Note that
thiswithin each customAttribute execution is the Raphael object for which the attr is being set. This means…3. Forcing custom attribute into the SVG or VML markup in the browser
Raphael doesn’t really support this, so only do this if you really, really need to. But if you really do need something in the markup that Raphael just doesn’t support, you can create a rudimentary control for manipulating it using
attrandanimateby usingpaper.customAttributesandelement.node(note that the documentation forelement.nodeis pretty much just the highly unhelpful “Don’t mess with it” – the reason you shouldn’t mess with it is, it gives you the SVG or VML element directly, which means Raphael doesn’t know about any of the changes you make to it, which may put your Raphael object out of sync with the element it controls, potentially breaking stuff. Unless you’re careful, and use a technique like this…).Here’s an example (assuming jQuery is also being used, jQuery isn’t essential but is more convenient) that sets the SVG property
dy, which allows you to control line spacing of Raphael text (note – example code not yet tested in VML/IE. will update if it doesn’t work in VML mode):Live jsfiddle example