Does anyone know how I can easily move segments in a path?
I tried:
layers["h"].children[0].segments[2].point.x+=3
But it doesn't move the handles..
Any help is much appreciated
Great! Thanks very much for the help - also for the function! Will come in very handy.
I'm using scriptographer to make a lettering tool..
Actually I used your idea of using layer names as one large array! came in very handy to construct an alphabet..
I let the user enter a string in the tool settings, which is then seperated into an array and then I can point to the corresponding layers to hand the correct ingredients per layer for the letters.. I'll clean it up soon to post it online (need to work on the letterforms still - they're very rudimentary still)
I just remembered I put a small screensnapz recording of it online already: http://www.paraphonic.com/modulartype_mp42.mov
function moveBy(layer, child, seg, disx, disy){ layers[layer].children[child].segments[seg].point.x+= disx; layers[layer].children[child].segments[seg].point.y+= disy; layers[layer].children[child].segments[seg].handleIn.x+= disx; layers[layer].children[child].segments[seg].handleIn.y+= disy; layers[layer].children[child].segments[seg].handleOut.x+= disx; layers[layer].children[child].segments[seg].handleOut.y+= disy; } moveBy("h", 0, 2, 0,20);
In order to speed things up, it is better to reference the segment once and then keep it in a variable like this:
function moveTo(layer, child, segment, pos){ var seg = layers[layer].children[child].segments[seg]; seg.point.x = pos; seg.handleIn.x = pos; seg.handleOut.x = pos; }
also, if you want to move a point by the value of another point, you can use the point's add() function:
var move = new Point(100, 200); seg.point = seg.point.add(move); seg.handleIn = seg.handleIn.add(move); seg.handleOut= seg.handleOut.add(move);
and using x and y variables instead of a point should work as well:
var x = 100; var y = 200; seg.point = seg.point.add(x, y); seg.handleIn = seg.handleIn.add(x, y); seg.handleOut= seg.handleOut.add(x, y);
I wonder wether handleIn and handleOut should contain relative values instead of absolute ones in the new version of Scriptographer. This would make such things much easier, modifying seg.point would move them automatically.
I would agree with handleIn and handleOut containing relative values..
It seems rather logical since in Illustrator the handles are always relative to the point. (i.e. when you drag a point, they move with it.)
Here's a function for moving multiple segments in one shape: (including Juerg's code cleanups)
function moveSegsBy(layer,child,segs,disx,disy){ for (i = 0; i < segs.length; i++){ var seg = layers[layer].children[child].segments[segs[i]]; seg.point = seg.point.add(disx,disy); seg.handleIn = seg.handleIn.add(disx,disy); seg.handleOut= seg.handleOut.add(disx,disy); } }
I'm not sure about this. How would you tell wether you want absolute or relative? While this may make sense in markup language, it does not really make sense in an API. It would only cause confusion.
But I think I will switch to relative values. It makes things so much easier.
I understand, but this would make things more complicated. I think generally having them relative instead of absolute makes sense for the reason Jonathan stated: When moving the point, the handles are moved automatically in Illustrator.
Adding such a behavior switch on a object level is not only something very unusal in a programming language, it also would cause confusion and increase complexity of the code, because one would allways have to set the mode first, in order to be sure it's the mode we want (otherwise another script might have changed the value before...).