JavaFX graphics performance and suitability for advanced animations

Richard Bair richard.bair at oracle.com
Fri May 31 20:38:53 PDT 2013


> If I fill the box with a darkish color (blue) the shimmering is barely detectable and with yellow it is less pronounced. Could it be that the shimmer is more pronounced to the eye if it is on the 'inside' of the box. Maybe if the inside of the border was kept crisp the eye is ok with the outside being soft (typically where shadow is, etc)? I don't know. 
> 
> If I speed up the animation the problems are much less noticeable but that's probably just that the eye doesn't have time to process it all. If I slow down the animation (10 seconds) then the shimmer is still noticeable, and it may be my eyes playing tricks or just coincidence but it seems worse just for last few pixels before the animation ends and turns around. Interestingly on the JScript one at this speed the jerkiness is more noticeable - in line perhaps with your comments that there are trade-offs either way with the various options. It would be nice if we all had retina displays and didn't have to worry about this sort of stuff. 

Incidentally, both of these techniques (careful choice of colors, choice of animation speed, etc) are classic techniques for getting great looking animations. Thicker lines, less contrast, non-linear animations, etc. We used to talk about all these years ago for the SwingX animation framework, and similar stuff is still done on the android side (if I'm not mistaken).

However if you've got a good example of what somebody is doing that is better than what we're doing, then for sure we need to understand how that is being done.

I modified your example so that it pixel snaps at each step, to see if that might be what is going on (definitely on the browsers I tried on my mac, both native to the mac and within Parallels, all I saw was pixel snapping. There wasn't an anti-aliased line in the house). This looks bad for me though in FX, I'm wondering what it looks like for you.

    public void start(Stage stage) throws Exception {
        final StackPane rootPane = new StackPane();
        VBox box = new VBox();
        box.setMaxSize(200, 200);
        box.setStyle("-fx-border-color: black; -fx-background-color: white; -fx-effect: dropshadow(two-pass-box , darkgray, 10, 0.0 , 4, 5);");
        rootPane.getChildren().add(box);
        createTranslation(box, 3, -200, -200, 200, 200).play();

        Scene scene = new Scene(rootPane, 1200, 800);
        stage.setScene(scene);
        stage.show();
    }

    protected Animation createTranslation(Node node, int seconds, int fromX, int fromY, int toX, int toY) {
        IntegerProperty xProperty = new SimpleIntegerProperty(fromX);
        IntegerProperty yProperty = new SimpleIntegerProperty(fromY);
        node.translateXProperty().bind(xProperty);
        node.translateYProperty().bind(yProperty);

        Timeline t = new Timeline(
                new KeyFrame(Duration.seconds(seconds),
                        new KeyValue(xProperty, toX, Interpolator.EASE_BOTH),
                        new KeyValue(yProperty, toY, Interpolator.EASE_BOTH)));
        t.setCycleCount(Timeline.INDEFINITE);
        t.setAutoReverse(true);
        return t;
    }


Notice the trick -- using a Timeline to pump values into IntegerProperty objects and then binding those to the node.

Richard


More information about the openjfx-dev mailing list