Mateus Viccari
Mateus Viccari

Reputation: 7699

Fade between images in JavaFX

I have an ImageView in which I want to display two images, one after another. I want the transition between these two images to have a fade effect. This is what I tried:

KeyFrame keyFrame1On = new KeyFrame(Duration.seconds(.2), new KeyValue(imageView.imageProperty(), image1, Interpolator.EASE_OUT));
KeyFrame keyFrame2On = new KeyFrame(Duration.seconds(.5), new KeyValue(imageView.imageProperty(), image2, Interpolator.EASE_OUT));
Timeline timelineOn = new Timeline(keyFrame1On, keyFrame2On);
timelineOn.setAutoReverse(false);
timelineOn.play();

But the transition between the images is solid, without fade. What am I doing wrong?

Upvotes: 1

Views: 3075

Answers (2)

Mateus Viccari
Mateus Viccari

Reputation: 7699

So what I had to do was just create another ImageView, then change the opacity of one of the image views. Here is the FXML:

<AnchorPane fx:controller="br.atualy.importacaocte.controllers.DragAndDropController" maxHeight="-Infinity"
            maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="195.0" prefWidth="195.0"
            style="-fx-background-color: transparent"
            xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
    <ImageView fx:id="imageView" fitHeight="195.0" fitWidth="195.0"
               pickOnBounds="true" preserveRatio="true">
        <Image url="@../img/drag_drop.png"/>
    </ImageView>
    <ImageView fx:id="imageViewHover" fitHeight="195.0" fitWidth="195.0"
               pickOnBounds="true" preserveRatio="true">
        <Image url="@../img/drag_drop_hover.png"/>
    </ImageView>
</AnchorPane>

And here is the code:

KeyFrame kf1 = new KeyFrame(Duration.seconds(0), new KeyValue(imageViewHover.opacityProperty(), 0));
        KeyFrame kf2 = new KeyFrame(Duration.seconds(.5), new KeyValue(imageViewHover.opacityProperty(), 1));
        KeyFrame kf3 = new KeyFrame(Duration.seconds(1.5), new KeyValue(imageViewHover.opacityProperty(), 1));
        KeyFrame kf4 = new KeyFrame(Duration.seconds(2), new KeyValue(imageViewHover.opacityProperty(), 0));
        Timeline timelineOn = new Timeline(kf1, kf2, kf3, kf4);
        timelineOn.setCycleCount(Timeline.INDEFINITE);

What it does is to create a "blink" effect between the two ImageViews.

Upvotes: 2

James_D
James_D

Reputation: 209225

The interpolator really isn't doing anything for you here (it just defines a mapping between the actual time and the parameter used to compute the values of the properties that are changing).

To implement a fade in/out you need to actually manipulate theopacityProperty of the imageView in the Timeline.

Try something like

KeyFrame keyFrame1On = new KeyFrame(Duration.seconds(0), new KeyValue(imageView.imageProperty(), image1));
KeyFrame startFadeOut = new KeyFrame(Duration.seconds(0.2), new KeyValue(imageView.opacityProperty(), 1.0));
KeyFrame endFadeOut = new KeyFrame(Duration.seconds(0.5), new KeyValue(imageView.opacityProperty(), 0.0));
KeyFrame keyFrame2On = new KeyFrame(Duration.seconds(0.5), new KeyValue(imageView.imageProperty(), image2));
KeyFrame endFadeIn = new KeyFrame(Duration.seconds(0.8), new KeyValue(imageView.opacityProperty(), 1.0));
Timeline timelineOn = new Timeline(keyFrame1On, startFadeOut, endFadeOut, keyFrame2On, endFadeIn);

Upvotes: 5

Related Questions