JavaFX Coverflow Part 1
Warning: Apple Inc apparently has a patent on this. I’m merely doing this for performance comparison purposes and for self-education only.
It’s been about 2 weeks since my first JavaFX session. My initial distaste for the YAML syntax is largely gone. I have avoided using Netbeans, as vim is sufficient. The absence of closing tags in YAML means that an editor which matches braces is essential. As a side note, I think 2 spaces for tabs is enough, otherwise, one would end up with too much white-space on a page.
Refactoring the previous Coverflow exercise into a CustomNode turned out to be a straightforward cut and paste operation. The presence of “bind” has cut out a lot of error-prone trigger-based coding. For example, note how I had extracted the width and height from the original code into attributes.
Now it’s time to add some animation. I haven’t figured out arrays in JavaFX yet. Presumably we’ll have to deal with a list of Cover instances. Further down the road, I’ll investigate how JavaFX scales when we have, say, 100 covers.
As it turns out, you can see that the animation syntax is pretty weighty, and takes up more source lines than the layout of the nodes itself. For Sun engineers: can we perhaps have some kind of scoping rule so that we don’t have to type EASEOUT so many times?
To run the following example,
javafxc -d . Coverflow.fx javafx coverflow.Coverflow
/* Coverflow.fx */
package coverflow;
import javafx.application.*;
import javafx.animation.*;
import javafx.input.*;
import javafx.scene.geometry.*;
import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.effect.*;
var c:Cover;
class Cover extends CustomNode
{
attribute height:Number=100;
attribute width:Number =100;
attribute angle:Number = 10; /* 0 to 10 */
function create():Node
{
return
Group
{
content:
[
Rectangle
{
onMouseClicked: function (e:MouseEvent) {t.start();}
width: 100 height: height x: 0 y: 0
fill: Color.WHITE
effect: Reflection { topOffset:0.0 topOpacity:0.30},
},
]
effect:
PerspectiveTransform
{
llx: bind translateX+0.0 lly: bind translateY+height*2
lrx: bind translateX+width lry: bind translateY+height*2-angle*2
ulx: bind translateX+0.0 uly: bind translateY+ 0.0
urx: bind translateX+width ury: bind translateY+angle
}
}
}
}
Frame
{
visible: true
title: "Coverflow Part 1"
closeAction: function() { java.lang.System.exit(0); }
width: 1024 height: 768
stage: Stage
{
fill: Color.BLACK
content:
[
c = Cover { opacity: 0.7 translateX: 100 translateY: 200 angle: 10 },
]
}
}
var t:Timeline = Timeline
{
autoReverse: true
repeatCount: 1
keyFrames: [
KeyFrame {
time: 0s
values: [
c.angle => 10.0 tween Interpolator.EASEOUT,
c.translateX => 100.0 tween Interpolator.EASEOUT,
c.translateY => 200.0 tween Interpolator.EASEOUT,
c.width => 100 tween Interpolator.EASEOUT,
c.height => 100 tween Interpolator.EASEOUT,
c.opacity => 0.7 tween Interpolator.EASEOUT,
]
},
KeyFrame {
time: 300ms
values: [
c.angle => 0.0 tween Interpolator.EASEOUT,
c.translateX => 150.0 tween Interpolator.EASEOUT,
c.translateY => 100.0 tween Interpolator.EASEOUT,
c.width => 200 tween Interpolator.EASEOUT,
c.height => 200 tween Interpolator.EASEOUT,
c.opacity => 0.9 tween Interpolator.EASEOUT,
]
},
KeyFrame {
time: 400ms
values: [
c.angle => 0.0 tween Interpolator.EASEOUT,
c.translateX => 160.0 tween Interpolator.EASEOUT,
c.translateY => 100.0 tween Interpolator.EASEOUT,
c.width => 200 tween Interpolator.EASEOUT,
c.height => 200 tween Interpolator.EASEOUT,
c.opacity => 1.0 tween Interpolator.EASEOUT,
]
},
]
}
1 Comment
Jump to comment form | comments rss [?] | trackback uri [?]