Reputation: 5598
I'm pretty new at SVG and Raphael, but I've been using Illustrator for many years, so I have some assumptions on how it works. I want to combine two paths which should return a single element.
I need to make a speech bubble, but it could be anything really. In this case I tried to make two rect
, one with round corners and another square rect
which was rotated. It looked alright, but when I tried to move the speech bubble, the rotated element moved in the wrong direction, because of the 45 degree rotation.
How can I compbine paths which I can later manipulate as if it was a single element/path?
Upvotes: 3
Views: 3930
Reputation: 34074
If you mean merging paths like using the Illustrator Pathfinder
panel - turning several paths into one path (not a set of paths), merging overlap - I'm pretty sure there's no direct Raphael or SVG equivalent.
The closest thing is, creating a compound path (aka composite path) - the equivalent of cmd-8
or Object > Make Compound Path
in Illustrator. This merges paths together into one path, but doesn't remove areas of overlap.
Basically, for a set paper.set( paper.path('M0,0 4,0 0,4z'),paper.path('M9,9 4,9 9,4z') );
, an equivalent compound path would be paper.path('M0,0 4,0 0,4z M9,9 4,9 9,4z');
- just joining the path definitions into one, each starting with its own M
.
Some differences to Raphael sets:
toFront()
changes the order within the set, and transforms centre around each item, like Illustrator's transform each
, unless you give the transform static co-ordinates. JSBIN demo - compare the gradients, and see how the compound pair is just one path on the DOM.
Here's a simple plugin that adds the ability to take a set and create a compound path from it:
Raphael.st.compoundPath = function(){
var positions = [];
this.forEach( function( element ){
positions.push( element.compoundPath() );
});
return positions.join('');
}
Raphael.el.compoundPath = function(){
var path = this.attr('path');
return path ? Raphael.parsePathString( path ).join('') : '';
}
Then use it like this:
var someSet = paper.set(paper.path('M0,0 4,0 0,4z'),paper.path('M9,9 4,9 9,4z'));
var compPath = paper.path( someSet.compoundPath() );
someSet.remove(); // if you want to replace the set with a compound path
Note that it only combines paths in a set - if you need to combine other shapes with paths, you'll need a way to convert them into paths first.
Upvotes: 2
Reputation: 5028
Here you go DEMO
var paper = Raphael('canvas',400,400),
r1 = paper.rect(100,100,200,100).attr({fill:'black'}),
r2 = paper.rect(130,130,140,40,5).attr({fill:'white','stroke':'white'}),
r3 = paper.path("M200 170L240 170 220 180z").attr({fill:'white', 'stroke':'white'}),
p = paper.set(r1,r2,r3);
// the rest of the code is in the demo
Note, that it is easier to create triangle via path()
and not worry about rotation.
Good Luck ;)
Upvotes: 2
Reputation: 1748
First thing is that you could push your 2 elements into a Raphael set which you would later move with Element.transform()
. This would let you apply the move handler once, and not twice.
Also for your issue, it is acually documented:
... There are also alternative “absolute” translation, rotation and scale: T, R and S. They will not take previous transformation into account. For example, ...T100,0 will always move element 100 px horisontally, while ...t100,0 could move it vertically if there is r90 before. Just compare results of r90t100,0 and r90T100,0. ...
Upvotes: 1