2

I'm having an issue with sets and how transforms are applied. I'm coming from a graphics background, so I'm familiar with scene graphs as well as the normal SVG group syntax, but Raphael is confusing me. Say I have a circle and a set, on which I want to apply a transform.

circle = paper.circle(0,0.5)
set = paper.set()

If I add the circle first, and then transform, it works.

set.push circle
set.transform("s100,100")

To make a 50 radius circle. If I reverse the order, however,

set.transform("s100,100")
set.push circle

The transform is not applied.

This seems as though it will break many, many rendering and animation type algorithms, where your groups/transforms hold your articulation state, and you add or remove objects to them instead of recreating the entire transform every time. Is there an option somewhere in the documentation that I am not seeing that addresses this, or was this functionality discarded in favor of simplicity? It seems very odd to be missing, given that it is supported directly and easily in the group hierarchy of SVG itself... do I need to manually apply the transform from the set to any children added after the set is transformed?

Eliran Malka
  • 15,821
  • 6
  • 77
  • 100
user1785797
  • 137
  • 1
  • 7

2 Answers2

6

Sets in Raphael are just simple Arrays.

When you perform some actions on set, Raphael goes through all members via for(...){} loop.

Raphael doesn't support SVG groups <g></g>

UPDATE Raphael's code:

// Set
var Set = function (items) {
    this.items = [];
    this.length = 0;
    this.type = "set";
    if (items) {
        for (var i = 0, ii = items.length; i < ii; i++) {
            if (items[i] && (items[i].constructor == elproto.constructor || items[i].constructor == Set)) {
                this[this.items.length] = this.items[this.items.length] = items[i];
                this.length++;
            }
        }
    }
},

As you can see, all items are stored in this.items which is array.

Roman
  • 3,799
  • 4
  • 30
  • 41
  • So why -1? :) I updated my answer with Raphael's code to show that it's true. – Roman Dec 23 '12 at 13:06
  • 1
    Thank you! :) BTW currently I'm working on my own Raphael extension which will support real SVG groups. – Roman Dec 24 '12 at 09:47
  • @oyatek did you ever come up with your ``-in-Raphael implementation? I think it is the one feature that's really missing if you want to create more complex graphics apps with raphael! – de. Mar 18 '14 at 21:49
3

Raphaël's sets are merely intended to provide a convenient way of managing groups of shapes as unified sets of objects, by aggregating element related actions and delegating them (by proxying the corresponding methods in the set level) to each shape sequentially.

It seems very odd to be missing, given that it is supported directly and easily in the group hierarchy of SVG itself...

Well, Raphaël is not an attempt to elevate the SVG specs to a JavaScript based API, but rather to offer an abstraction for vector graphics manipulation regardless of the underlying implementation (be it SVG in modern browsers, or VML in IE<9). Thus, sets are by no means representations of SVG groups.

do I need to manually apply the transform from the set to any children added after the set is transformed?

Absolutely not, you only need to make sure to add any shapes to the set before applying transformations.

Eliran Malka
  • 15,821
  • 6
  • 77
  • 100
  • Thanks for the response. I'd be really curious to hear what technical design reason there is for sets *not* being groups, because at first glance it seems like a rather... odd... decision. It makes some ways I'm used to manipulating scene graphs work very differently. I can think of numerous examples of when you would be adding/removing/enabling/disabling children of a group *after* you know what its transform is. – user1785797 Dec 23 '12 at 21:22
  • well, if you're interested in Raphaël's design decisions and motivations, you could try and [contact Dmitry Baranovskiy](http://dmitry.baranovskiy.com/), the library's author. you may also (and should) **[browse the code](https://github.com/DmitryBaranovskiy/raphael/)**. i suppose JavaScripters are accustomed to arrays so dealing with a live set of objects comes naturally, and again, `set`s do not represent groups as to serve as an abstraction layer (VML is lacking the *groups* concept). – Eliran Malka Dec 24 '12 at 10:50
  • 1
    If the primary purpose to abstract the VML/SVG switch, I guess that makes more sense. Everyone was recommending it as a general purpose interface for drawing SVG, so I didn't realize the degree to which that drove its design. – user1785797 Dec 26 '12 at 04:18