JavaFX graphics performance and suitability for advanced animations
Daniel Zwolenski
zonski at gmail.com
Sat Jun 1 22:53:58 PDT 2013
I tried your pixel snapping one and it is on par with the JScript version,
so it could be that either my system or my eye prefers that option. Good to
know we can switch between them at least to cater for different devices.
That project I captured in the last email had a fixed brand/model of tablet
that it was on so in that case it's good to be able to maximise performance
for that particular device.
I tried to taking screen captures of the different scenarios but it's too
fine detail and the animation just looks crap on all of them in the
captures.
I'm hearing you that this is a messy problem with no ideal, and some
options might be better in case A but worse in case B. Happy to say that
one is done and dusted and not worth going into deeper. I think the trick
will be to use coloured backgrounds - windows metro style.
On Sat, Jun 1, 2013 at 1:59 PM, Richard Bair <richard.bair at oracle.com>wrote:
> > This looks bad for me though in FX, I'm wondering what it looks like for
> you.
>
> I ran with the pulse logger and definitely there is no frame taking more
> than a couple milliseconds. Things look awful because this example is
> truncating (by casting to int) instead of rounding, and so on each frame
> the rectangle is pixel snapped to a position that may be closer, or farther
> away from the expected location and our brain sees it. To test this theory,
> one thing I did was modify the sample so that instead of taking 3 seconds
> to travel 400 pixels, I use 4 seconds and I removed the EASE_BOTH
> interpolators. In this case the expected location on each frame is exactly
> a pixel boundary, and of course it looks smooth. Note though that the
> border still looks fuzzy (to me) but this is because the refresh rate on
> the monitor or possibly the eye is exhibiting a motion blur.
>
> 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, 4, -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),
> new KeyValue(yProperty, toY)));
> t.setCycleCount(Timeline.INDEFINITE);
> t.setAutoReverse(true);
> return t;
> }
>
>
>
>
> And here is another version which instead keeps the interpolator and the 3
> second movement (so we're back to unexpected irregular positions) and we
> pixel snap by rounding instead of by truncating.
>
> 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();
> }
>
> class RoundingValue extends SimpleDoubleProperty {
> public RoundingValue(int initialValue) {
> super(initialValue);
> }
>
> @Override public void set(double newValue) {
> super.set(Math.round(newValue));
> }
> }
>
> protected Animation createTranslation(Node node, int seconds, int
> fromX, int fromY, int toX, int toY) {
> RoundingValue xProperty = new RoundingValue(fromX);
> RoundingValue yProperty = new RoundingValue(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;
> }
>
>
> This looks pretty good perhaps this is what you are seeing in the browser?
>
> Richard
More information about the openjfx-dev
mailing list