JavaFX script – functional and procedural programming, and animation

how-to
Dec 11, 20083 mins

Functional programming and procedural programming often provide different views of the same thing. When I declare a function, such as

   y = 2x

I may think of this as a procedure (sequential process): “Give me something, I’ll double it, and then I’ll give it back to you”. However, I may also think of it as simply a declaration of unchanging state: for example as an infinite line on a graph, without regard to any real process that may produce it.

In natural language, and in the language of the mind it’s clear that both conceptualizations are useful and constantly used.

In JavaFX script, functional relationships may be expressed using the bind operator. Meanwhile, procedural code may sequentially change the values of the independent variables of such expressions and the system will automatically maintain those relationships.

Both procedural state changes and functional relationships derived from them are conceptually “instantaneous”.

By contrast, “animation” describes what we perceive to be continuous state changes over time.

Any JavaFX script variable may be “animated” – not just those that represent properties of actual visual elements. Animating a variable amounts to assigning new values to it “often enough” to create the perception of continuous change. For smooth animation of graphics “often enough” means at the refresh rate of your display (60 times per second for a typical LCD display).

Although possible, it would be quite onerous to specify each discrete change for each variable procedurally at each time step, and equally onerous to attempt to specify every variable as a function of time.

Fortunately, traditional animators invented an easier system, which has been adopted in computer animation. The animator (or programmer in the case of JavaFX script) specifies only the “key” states of a variable at various points along the time dimension, and provides an interpolation function to automatically compute the “in-between” states.

Although an animation can target any JavaFX script variable, it isn’t necessary for the animation itself to directly modify all the variables it may affect. Instead, the programmer can place bindings and triggers on the variables targeted by the animation, which express additional effects.

So, for example, if I wanted to have rectangle whose height was twice its width and whose size was animated over one second I could write something like this:

    var width: Number;  // animation target
    var height = bind width * 2; // height has functional dependency on width

    var t = Timeline {
        keyFrames:   // list of key states
        [KeyFrame {
            time: 0s
            values: width => 100 // width is 100 at zero seconds
        },
        KeyFrame {
            time: 1s
            values: width => 200 tween LINEAR  // width is 200 at one second (and linearly interpolated in between)
        }]
    }

    t.play(); // procedurally start the animation

Although the code only animates the width variable, the height variable is also animated as a side effect of its functional dependency.

You’ve probably noticed there’s no actual rectangle here. That’s intentional. I can connect a visual rectangle to this logic separately in a decoupled way using additional functional dependencies:


   Rectangle {
       height: bind height
       width: bind width
       fill: BLUE
   }

Throwing that onto a Stage/Scene would give me graphical animation of a blue rectangle.