paperJS (paper.js) JavaScript Library walk through by Brett Paufler -
9-7-13
JavaScript Tutorial & paper.js primer
ONFRAME() & ROTATE()
ONFRAME()
To me, the onFrame() method is fairly straightforward.
This is the barebones code to 'drop' the black center circle.
function onFrame(event){
centerCircle.position.y += .1;
}
I say barebones, but the 'event' argument can be optional if it's never
used. Still, I say why not include it. Never hurts.
The Y coordinate is reversed from the Cartesian system, so += drops the
ball. And that's all there is to that animation.
This is the full onFrame() method for this page:
function onFrame(event){
centerCircle.position.y += 0.1;
animateSwingAngle();
updateFeedbackPointText();
}
The first line creates the function, which is sort of odd, in that it's a paper.js function. From there:
centerCircle.position.y += 0.1;
drops the center ball
animateSwingAngle();
is a user created function that animates the rest of the graphics
updateFeedbackPointText();
is another user created function
that updates the PointText; but hopefully, you already knew that from
it's name
I like the rule that functions and methods should start with a
verb. They do something, so start with a verb that describes what
they do.
I won't list out all of the code for the updateFeedbackPointText()
function, suffice to say the remaining 15 PointTexts follow the same
pattern:
function updateFeedbackPointText(){
FBText[1].content = 'CP = ' + CP;
FBText[2].content = 'swingPoint = ' + swingPoint;
FBText[11].content = 'mp';
FBText[11].position = swingPathInner.bounds.center;
}
To change the text, the content attribute is updated, with both a
string describing what value I am calling and the raw script code for
the value in question. In: FBText[1].content = 'CP = ' + CP;
FBText[1] the PointText Object in question
.content it's content attribute (the text to display)
'CP = ' A string value, this prints to screen exactly as inputed
+ CP;
+ canconates, the CP
variable, which in this case points to a paperscript Point Object
This line of code updates the position of the FBText[11] variable, so it rotates at the innner line's midpoint 'mp':
FBText[11].position = swingPathInner.bounds.center;
So, just like with the circle, updating an Object's position is one of the easiest ways to animate it.
Also, I should mention somewhere: to create a user defined function,
the function keyword prescedes the name, much like var precedes a
variable name when it is being declared.
So, this is the code for the animateSwingAngle() function (stuff in red, I elaborate on below):
function animateSwingAngle(){
// swingPoint & SwingPathInner, seperate, but
both by rotate()
swingPoint = swingPoint.rotate(1, CP);
swingPathInner.rotate(1, CP);
swingPointCircle.position = swingPoint;
// swingPathOuter position by swingPoint & then
rotate
swingPathOuter.position = swingPoint;
swingPathOuter.rotate(-1, swingPoint);
// green endPointCircle
swX = swingPathOuter.bounds.width;
swY = swingPathOuter.bounds.height;
Xtemp = (0.5 * swX) - swX;
Ytemp = (0.5 * swY) - swY;
var tempPoint = new Point(Xtemp, Ytemp);
trueEndPoint = swingPoint + tempPoint;
endPointCircle.position = trueEndPoint;
}
swingPoint = swingPoint.rotate(1, CP);
swingPathInner.rotate(1, CP);
rotate() is a paper.js method. In
retrospect, I probably should have called the second line out as:
swingPathInner = swingPathInner.rotate(1, CP);
The first line would not run until I
assigned the rotated value back to itself. Don't ask me why I
don't need to do the same for the path. But I have a hunch there
will be less possiblity of a downstream bug if the revised assignment
is used (i.e. swingPathInner = swingPathInner.rotate(1, CP);).
The syntax for rotate is myObject.rotate(degrees [,optionalPoint]).
There are two line segments in this animation.
Perhaps there is an easy way of finding the endPoint of a line in
paper.js, but if there is, I never found it. All of those
PointText's going down side of the canvas list off a multitude of
properties for the inner line. endPoint is not one of them (in
fact, endPoint is just a random conglomeration I'm using, here and now
to signify end point, it's not part of the paper.js library that I know
of).
So, to find the endPoint of the innerLine
(swingPathInner), I created another point and rotated that
separately. Then, I used that swingPoint to mark the center of
the outerLine (that's what this line does):
swingPathOuter.position = swingPoint;
Note: how this has absolutely nothing to do with
swingPathInner. The two paths are not joined and I am not
computing the postion of the one off the other. This is a
shortcoming to be sure (or simply something I don't understand about
the library, yet).
Having created the outerLine (swingPathOuter), this line of code rotates it in the opposite direction.
swingPathOuter.rotate(-1, swingPoint);
Notice how an assignment is not required. Upon
retrospect, and as stated above, I'm not convinced this is the
cleanest. Next time, I'll probably code it out longhand as
swingPathOuter = swingPathOuter.rotate(-1, swingPoint);
One of the reasons I say all this is that in the
last line of highlighted (red above) code, I take five lines to do what
could easily be done in three if not a single line of code (and there's
even more code than this, as I had to declare all these variables as
global).
swX = swingPathOuter.bounds.width;
swY = swingPathOuter.bounds.height;
Xtemp = (0.5 * swX) - swX;
Ytemp = (0.5 * swY) - swY;
var tempPoint = new Point(Xtemp, Ytemp);
Originally, I had something along the lines of:
var Xtemp = (0.5 * swingPathOuter.bounds.width) - swingPathOuter.bounds.width;
And although this appears to be syntaxically the
same as the above to me (the difference being syntaxical sugar as they
say), in reality it's not. Now, I don't know for sure, but I'm
guessing that what happens is that since var is not declared as a type
(in my code I declare as var swX = 0;, so clearly it's an
integer). But if var Xtemp is not explicitely declared, the
compiler guesses, and in this case, I believe it guesses var Xtemp =
{}; And so, what happens is that object path addresses are
getting added together (or really, who knows). All I know is that
instead of working as intended, my pendulum would swing back and forth,
then swing off the page ('working' it's way around the circle) and then
swing back in from the other side. Interesting, but not what I
wanted.
Anyway, long story short. There are two lessons in there:
- Take short steps. Smaller incremental steps are better than
lots of confusion lumped together. Humans can't read it.
And it's becoming increasingly appearent to me that neither can
computers.
- The program didn't do what I wanted, but it did something
cool. I am way too locked in to what I want and not what the
computer is willing to give me. I need to loosen up more and go
with the flow. (And there's probably a surfing analogy in there
somewhere if one cares to look for it.)
If that second point doesn't make a lot of sense, perhaps I should
state explicitly, I wanted that green circle to be attached to the end
of the swingPathOuter and not hop around. Hopping is cool.
Pendulums swinging across the page at random are cool. But they
are not what I wanted. This is basically a failed program.
That green ball is not doing what I want it to do. But then,
doesn't it sort of look like it might be a lot (and I mean, a lot)
harder to code something like that out on purpose. So, um, yeah,
on retrospect, it was hard (to get my mind screwed on straight), but I finally got that green ball to do
exactly what I wanted and hop from rotating endPoint to rotating
endPoint. Stick with me and you'll be sure to see lots of
interesting effects like that in the pages ahead, you know, as I try to
achieve one thing and somehow manage to achieve something totally
different. Ride the wave, baby. Ride the wave.
Anyhow, I think that more than adequately covers both onFrame() &
rotate(), at least as an initial primer. But having got bogged
down in what I wanted to do (a compound pendulum), I never really
explored what would be easy to accomplish (rotating stars), so the next
page is going to have a lot of rotate() examples as I explore the
information to be had from view.center.
And yes, I'm going to code it all as assignments (i.e.):
myObject = myObect.rotate(x);
previous (Affine Transfrom Demo) paper.js tutorial
index next (view.center)
Back to BrettCode Home
Brett Words
my writing site (Home to the writing of Celli the Happy Go Lucky
Celaphopod, Eddie Takosori, Fritz Heinmillerstein, Morgan Feldstone,
Kevin Stillwater, and of course, me, your host, Brett Paufler)
paper.js official site = http://www.paperJS.org
© Copyright 2013 Brett Paufler