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:
  1. 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.
  2. 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