How to Set/Apply an Absolute Rotation Angle?

2,272 views
Skip to first unread message

Philip Weaver

unread,
Apr 22, 2012, 12:45:12 AM4/22/12
to pap...@googlegroups.com
I want to set an absolute (not relative) rotation on an item. I haven't figured out how to do this. When the following code is called repeatedly, it rotates by 5 degrees each time. I want to set the rotation - not change it.

Thanks,
Philip

var matrix = new paper.Matrix(1.0, 0, 0, 1.0, 0, 0);
matrix.setToRotation(5, item.position.x, item.position.y);
item.transform(matrix);

Joost van Pinxten

unread,
Aug 7, 2013, 7:00:05 AM8/7/13
to pap...@googlegroups.com
I'd like to know how to do this too! I'm not inclined to add state information to my own object about the rotation that I've already applied, so that I can determine the delta-rotation (or even worse, concatenating inverse rotation/translation/shearing matrices).

I've tried to 'reset' the transformation matrix, but it seems that this is still set to identity, even after applying a .rotate(30). What is the Paper.js vision on setting an absolute rotation?

Op zondag 22 april 2012 05:45:12 UTC+1 schreef Philip Weaver:

Joost van Pinxten

unread,
Aug 7, 2013, 9:20:37 AM8/7/13
to pap...@googlegroups.com
What works for me (but it is a kludge):

- create an instance of the thing you want to rotate (absolutely), place it, but hide it
- on each 'update', create a clone and set the rotation on the clone (and don't forget to delete the old clone!)

Op woensdag 7 augustus 2013 12:00:05 UTC+1 schreef Joost van Pinxten:

Mikael Honkala

unread,
Aug 8, 2013, 12:41:40 AM8/8/13
to pap...@googlegroups.com
Just out of curiosity, did you use Symbol for the copying?

Also, did you try putting the single Item in a Group and setting the group's transformContent to false, as discussed here earlier?

Joost van Pinxten

unread,
Aug 8, 2013, 3:10:27 AM8/8/13
to pap...@googlegroups.com
You mean as described in https://groups.google.com/forum/#!searchin/paperjs/transformContent/paperjs/45jmb70OKWc/MZ_AZU4Czx4J ? (would be nice if you had put that link in your post ;-))

No, I did not use a group with transformContent or a symbol; but it did give me insight in the way that Paper handles transformations and provides the argumentation (although I don't quite fully understand) why the transformation matrix is identity. Using a Symbol could improve the implementation, but I don't have many copies of the same thing active at one time (just one actually).

Thanks for pointing this out to me.

Op donderdag 8 augustus 2013 05:41:40 UTC+1 schreef Mikael Honkala:

Jürg Lehni

unread,
Aug 8, 2013, 4:07:41 PM8/8/13
to pap...@googlegroups.com
When transformContent is set to true, it means that whatever transformation you apply to the group gets passed on to all its children instead, therefore the group itself is not actually transformed, and its matrix remains the identity.
> --
> You received this message because you are subscribed to the Google Groups "Paper.js" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to paperjs+u...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Joost van Pinxten

unread,
Aug 8, 2013, 4:49:03 PM8/8/13
to pap...@googlegroups.com
From the docs (http://paperjs.org/reference/group/#transformcontent):

"Specifies whether the group applies transformations directly to its children, or wether they are to be stored in its item.matrix" (which should read 'whether' instead of 'wether' btw ;-))

That will probably make sense from an implementation point of view (which I'm not concerned with ;-)) and as a user, I am not aware that this is by default set to true (and this is not mentioned on the docs). Not being able to find this single line has got me confused, and there are no pointers to it, for so far as I can tell. This means effectively, that as a user, any shape I try to manipulate through a transformation will simply not behave as expected. Although I think for many purposes it will be alright, this behaviour should be made apparent in the tutorials, examples and references.

The simplest example that I can come up with right now, is the use of a user-input field which allows the user to set the absolute rotation of an element; this should provide absolute feedback, without the developer having to save that state information itself IMHO.


You received this message because you are subscribed to a topic in the Google Groups "Paper.js" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/paperjs/R3O0peJPFc0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to paperjs+u...@googlegroups.com.

Jürg Lehni

unread,
Aug 8, 2013, 6:30:18 PM8/8/13
to pap...@googlegroups.com
Yes Item#transformContent is something we recently added, which is why it's missing from the docs.

Initially, Paper.js only had matrices for Raster and PlacedSymbol. Then we added it to all items to allow Flash-style matrix nesting, but had Path always apply transformations directly to its contents (the Segments describing the geometry), since not doing so would have been confusing when dealing with positions of Segments, hit-testing on a user level, drawing tools, etc. This still caused incompatibility with many existing examples and projects, where Group was being used, so we decided to extend that default behavior of alway applying transformations to the content to Group too, and we introduced a second type, called Clip, which did not transform contents but stored transformations in the matrix instead.

Then SVG importing came along, and required the Clip behavior in Group, so I merged the two, removed Clip again (of which the name was a bit confusing too, since it could mean a clipping path), and added this #transformContent property which controls the transformation behavior.

I'm still not 100% happy with the current state, which is why the documentation has not been improved yet, and also one of the reasons for version 1.0 still not being rolled out.

I'm contemplating introducing again a MovieClip-style class that works more the way people are used to form flash (that's what the idea behind Clip was). This class could then later also get support for keyframe animation...

I'm curious to hear other people's thoughts on this.

Jürg

PS: Thanks for pointing out the typos. I fixed that now, will roll out automatically into the online docs tomorrow.

Joost van Pinxten

unread,
Aug 9, 2013, 5:25:28 AM8/9/13
to pap...@googlegroups.com
Alright, I did not know this was a recent development, thanks for this insightful reply! I see now that the default behaviour needs to be preserved just to provide backwards-compatibility.

I'm still quite unsure if Paper.js has provided means before to e.g. rotate a rectangle based on an absolute angle? From my (probably much simplified) perspective, the original definition should not be 'destroyed', so that when the transformations are reset, they can still be drawn like their original definition. This would allow you to reset it to the original definition (equivalent to setting the transformation matrix to the identity matrix) and then be able to apply a different transformation.

I've got some experience with the QtGraphicsItem interface and this provides simple direct stuff like #setScale, #setRotation, #setTransformationOrigin and #setPosition. Also, any group containing an item, will also inherit the (applied) transformation matrix from its parent, which makes moving around groups of elements trivial to do. I know that Paper.js is taking a somewhat different approach, and the approach that Qt's 2D drawing framework (QGraphicsScene and QGraphicsView) has taken is more similar to the way e.g. 3D libraries like OpenGL and Direct3D operate; chaining of (small) matrices is a very efficient operation.

https://qt-project.org/doc/qt-4.8/qgraphicsitem.html#transformations
https://qt-project.org/doc/qt-4.8/qgraphicsitem.html#setTransform
https://qt-project.org/doc/qt-4.8/qgraphicsitem.html#setTransformations

Most probably, I'm not stating any new information, but I'd just want to clarify in which way I like to think about the items on a canvas.

If I come across any other interesting ideas or pages, I'll post them here.

Op donderdag 8 augustus 2013 23:30:18 UTC+1 schreef Jürg Lehni:

Jürg Lehni

unread,
Aug 9, 2013, 1:08:18 PM8/9/13
to pap...@googlegroups.com
Paper.js focuses heavily on the direct manipulation of vector graphics, paths, segments, handles, anchor points, etc.

That's why we decided to have path items represent their geometry alway in coordinates that are directly relating to their parent context (e.g. the layer or group they are in), meaning they don't store transformation matrices but apply them instead to their geometry.

There is a shape contstructor for the representation of simple forms that are not described by bezier segments: circle, ellipse, rectangle, and soon rounded rectangle. These shapes use matrices for their positioning, and thus will exhibit the behavior you are used to from Qt.

If you wan this same behavior for path items, then you simply have to put them into a group that has #transformContent set to false at the moment. You could try setting #transformContent to false directly on path, but I'm not sure if this would work correctly with all the hit-testing stuff currently.

But in my eyes using #transformContent is not intuitive enough, which is why I'd like to introduce a new constructor, e.g. MovieClip, which always uses transformations, and later on offers key-framing.

I think this way, we can offer the best of both worlds.

We had initially chosen this approach because paper.js focuses heavily on simplifying the API for teaching purposes. Having to explain matrices to people who just learned to program is simply not helping. Having to explain why the points you're adding to a path do not appear where you expect them to doesn't help either.

I hope that makes sense?

Oh, and I just remembered: We absolute need a #localToGlobal() and a #globalToLocal() method on Item!

Best,

Jürg

plug...@googlemail.com

unread,
Sep 17, 2013, 9:28:15 AM9/17/13
to pap...@googlegroups.com
i would love to have a behaviour like flash: absoute rotation, absolute scaling.
matrices are really bad stuff for people who want to design :)

and #localToGlobal and #globalToLocal would also be very nice!

Best,
Eugen

Jürg Lehni

unread,
Sep 17, 2013, 1:59:36 PM9/17/13
to pap...@googlegroups.com

On Sep 17, 2013, at 06:28 , plug...@googlemail.com wrote:

> i would love to have a behaviour like flash: absoute rotation, absolute scaling.
> matrices are really bad stuff for people who want to design :)

Well you currently do, no? That's what Path and Group do at the moment, exactly for the reasons you are stating.
Other items can't do this for you though, e.g. Raster or PlacedSymbol.

> and #localToGlobal and #globalToLocal would also be very nice!

Working on it!

J

Felix Turner

unread,
Sep 23, 2013, 3:55:35 PM9/23/13
to pap...@googlegroups.com
To answer the original question: "How to Set an Absolute Rotation Angle?" Answer is you cannot directly. One solution is to use an additional property called lastRotation.e.g:

function onFrame(event) {
  lastRot = myItem.matrix.rotation;
  var newRot  =  90;
  myItem.rotate(newRot - lastRot);
}

Mikael Honkala

unread,
Sep 23, 2013, 10:54:55 PM9/23/13
to pap...@googlegroups.com
Felix, did you test the code you provided? According to all the discussion so far, it should not work, as Item.matrix does not provide the current rotation.

Felix Turner

unread,
Sep 24, 2013, 3:15:24 PM9/24/13
to pap...@googlegroups.com
Just re-created a test case. It seems that matrix.rotation does return for SVG items, but not for a path or group. The docs on matrix.rotation also makes it sound not 100% reliable: http://paperjs.org/reference/matrix/#rotation

Jürg Lehni

unread,
Sep 24, 2013, 6:17:30 PM9/24/13
to pap...@googlegroups.com
As stated before, transformations are directly applied to the contents of Path and Group items, to simplify working with coordinates when drawing things, therefore rotations will not be stored in their #matrix property. If you want to keep the rotation information, put your Path into a Group, and set #transformContent to false on the group. This will have the wished effect.

The rotation can only be extracted reliably from the matrix as long as you don't mix shearing and rotating. that's what the documentation refers to.
Reply all
Reply to author
Forward
0 new messages