How to scale geometry without scaling StrokeWidth?

722 views
Skip to first unread message

bhagwan

unread,
Apr 6, 2012, 6:27:03 PM4/6/12
to Paper.js
Having trouble scaling. No matter where I put the
style WRT the scale, the stroke width is always
scaled along with the geometry. I want to scale the
geometry (i.e. from a 0,1 coordinate system) to the
window size without increasing the strokeWidth.

gridG.scale(100);
gridG.style = gridStyle;

--
Thanks

Alex Blackwood

unread,
Apr 6, 2012, 9:43:46 PM4/6/12
to Paper.js
You want to use the transform function with a matrix item, not the
scale function:

var c = new Path.Circle(new Point(100,100),50);
c.strokeWidth=25;
c.strokeColor='black';
c=c.clone();
c.strokeColor='red';

//scale 50% and offset 50px in x and y
m = new Matrix(.5,0,0,.5,50,50);

c.transform(m);

bhagwan

unread,
Apr 9, 2012, 12:28:41 AM4/9/12
to Paper.js
Thanks, Alex. That worked. I'm still a bit confused about
groups--the styles seem to scale on them even if transform
is used:

var circG = new Group();
var c = new Path.Circle(new Point(100,100),50);
c.strokeWidth=1;
c.strokeColor='black';
circG.addChild(c);
c=c.clone();
c.strokeColor='red';
//scale 50% and offset 50px in x and y
mm = new Matrix(.5,0,0,.5,50,50);
circG.addChild(c);
c.transform(mm);
mmm = new Matrix(.5,0,0,.5,0,0);
circG.transform(mmm);

I'm also confused by the rendering model. The docs
say paper.js supports a scene graph but it looks to
be an odd one (to me). In your code, the path c seems to be
automatically inserted into the scene graph (it's drawn
without an 'add' of any sort). I assume when you do
the clone (also into c) the reference to the first circle
is lost (but it's still in the scene graph).

If we insert paths into groups are they then drawn twice
(once by the 'default' insertion and again by the insertion
of the group)?

Thanks again for the help. If there is documentation that
explains this could someone point me to it?
Message has been deleted

Alex Blackwood

unread,
Apr 9, 2012, 5:57:11 PM4/9/12
to Paper.js
The strokeWidth should be static, even when transforming groups. For
example:

var circG = new Group();
var c = new Path.Circle(new Point(100,100),50);
c.strokeWidth=25;
c.strokeColor='black';
circG.addChild(c);
c=c.clone();
c.strokeColor='red';
mm = new Matrix(.5,0,0,.5,50,50);
circG.addChild(c);
c.transform(mm);

//clone and transform 200% and move (100,-50)
circG=circG.clone();
mmm = new Matrix(2,0,0,2,100,-50);
circG.transform(mmm);

Paper.js does indeed have a scene graph. Each object is issued an id
integer, or optionally a name. Whether or not a given object is still
referenced by a variable, it can be accessed by either the .id/.name
property or its index in the project hierarchy. Check out
http://paperjs.org/tutorials/project-items/project-hierarchy/ for some
examples.

As for the documentation, I've found the comments in the source code
to be the best reference.

bhagwan

unread,
Apr 9, 2012, 11:26:08 PM4/9/12
to Paper.js
Thanks again for the help. I will take a look at the source
on GitHub.

bhagwan

unread,
Apr 10, 2012, 1:03:18 AM4/10/12
to Paper.js
Alex,

I've played with this a little more. It appears that style is
not static on any grouping type of object (Group, CompoundPath).

I put a JSFiddle up at http://jsfiddle.net/bhagwan/XVGLt/2/
to experiment (some of my code and yours). You can see that
strokeWidth is scaled for Group and CompoundPath.

I suspect that one needs to iterate over the components of
the Group (once it's been filled with Paths) and scale each
individually.

--
Al

bhagwan

unread,
Apr 10, 2012, 1:09:27 AM4/10/12
to Paper.js
Make that http://jsfiddle.net/XVGLt/3/

I've never tried JSFiddle before. Here's the code
in case the fiddle doesn't show as public:

<canvas id="canvas" resize keepalive="true"></canvas>

<script type="text/paperscript" canvas="canvas">
var gridStyle = {
strokeWidth: 1,
strokeColor: 'black'
};
var mat = new Matrix(100, 0, 0, 100, 100, 100);
var cp = new CompoundPath();
cp.moveTo(new Point(0,0));
cp.lineTo(new Point(1,1));
cp.moveTo(new Point(1,0));
cp.lineTo(new Point(0,1));
cp.style = gridStyle;
cp.transform(mat);

mat = new Matrix(100, 0, 0, 100, 100, 300);
var p = new Path(new Point(0,0), new Point(1,1));
p.style = gridStyle;
p.transform(mat);
p = new Path(new Point(1,0), new Point(0,1));
p.style = gridStyle;
p.transform(mat);

var circG = new Group();
var c = new Path.Circle(new Point(100,500),50);
c.strokeWidth=25;
c.strokeColor='black';
circG.addChild(c);
c=c.clone();
c.strokeColor='red';
mm = new Matrix(.5,0,0,.5,50,250);
circG.addChild(c);
c.transform(mm);

//clone and transform 200% and move (100,-400)
circG=circG.clone();
mmm = new Matrix(2,0,0,2,100,-400);
circG.transform(mmm);
</script>


Alex Blackwood

unread,
Apr 10, 2012, 9:07:07 AM4/10/12
to Paper.js
Ah, I've been using a version from Thu Nov 10 18:30:18 2011 in my test
directory. It looks like they've added a boolean flag to control
transforming the group as rendered or recursively.

circG.transform(mmm,true);

On Apr 9, 10:09 pm, bhagwan <allen.mcpher...@gmail.com> wrote:
> Make thathttp://jsfiddle.net/XVGLt/3/

Jonathan Puckey

unread,
Apr 10, 2012, 9:42:24 AM4/10/12
to pap...@googlegroups.com
Sorry for not replying to you earlier - indeed, you need to pass boolean true as the last argument to scale the points of paths within a group. This works for all transform functions, including item.rotate and item.scale.. This is a relatively new feature and therefore could be under documented.

bhagwan

unread,
Apr 10, 2012, 4:27:50 PM4/10/12
to Paper.js
Thanks, Jonathan and Alex. That did the trick.

As Alex suggested, I will try and examine the source in the future.
Reply all
Reply to author
Forward
0 new messages