Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ImageView Sprite Animation with JavaFX

I'm trying to create an sprite animation inside a login window (stage) with JavaFX that plays once the user get the login and password information. I tried to use the class publish by Michael Heinrichs in his blog post about sprite animations with JavaFX but I can't make it work, mostly because I don't understand how to create this animation inside an ImageView without using the start method (which doesn't work in my case either).

This is the code I have in the FXML file for the Login Stage:

<GridPane alignment="CENTER" hgap="10.0" vgap="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="crud.controller.MainController">
    <padding>
        <Insets bottom="25.0" left="25.0" right="25.0" top="25.0" />
    </padding>
    <children>
        <ImageView fx:id="loginAnimationImageView" GridPane.columnIndex="0" GridPane.halignment="CENTER" GridPane.columnSpan="2" GridPane.rowIndex="0">
            <image>
                <Image url="@../assets/shop-sprite.png" />
            </image>
        <viewport>
            <Rectangle2D height="130.0" width="131.0" />
        </viewport>
        </ImageView>
        <Label text="Usuario" GridPane.columnIndex="0" GridPane.halignment="RIGHT" GridPane.rowIndex="2" />
        <TextField fx:id="loginTextField" onAction="#onEnterTextFieldAction" GridPane.columnIndex="1" GridPane.rowIndex="2" />
        <Label text="Contraseña" GridPane.columnIndex="0" GridPane.rowIndex="3" />
        <PasswordField fx:id="passwordTextField" onAction="#onEnterPasswordFieldAction" GridPane.columnIndex="1" GridPane.rowIndex="3" />
        <Button fx:id="loginButton" onAction="#loginButtonAction" text="Ingresar" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.rowIndex="5" />
    </children>
</GridPane>

Inside the controller class I tried to create a launching method but firt, I have not idea how to launch it at the same time the stage open itself, and second, when I try to call the method from a button it tries to render the image (modify the space need it for the image) but it show nothing.

Here's the code:

@FXML private void launchAnimation() {
    loginAnimationImageView = new ImageView(IMAGE);
    loginAnimationImageView.setViewport(new Rectangle2D(OFFSET_X, OFFSET_Y, WIDTH, HEIGHT));

    final Animation animacion = new SpriteAnimation(
            loginAnimationImageView,
            Duration.millis(1000.0),
            COUNT, COLUMNS,
            OFFSET_X, OFFSET_Y,
            WIDTH, HEIGHT
    );

    animacion.setCycleCount(Animation.INDEFINITE);
    animacion.play();
}

Finally, here are the constant declarations:

private static final Image IMAGE = new Image("https://i.cloudup.com/1VA2FCnqY6-2000x2000.png");
private static final int COLUMNS  = 4;
private static final int COUNT    = 12;
private static final int OFFSET_X = 0;
private static final int OFFSET_Y = 0;
private static final int WIDTH    = 131;
private static final int HEIGHT   = 125;

This is how the login stage looks right now, and I want to animate the logo I have for it:

enter image description here

Can you guys help me to understand how to use the image view with this case?

There's any change I can use ImageView to create this kind of effect or I'm just wasting my time?

like image 298
David Gomez Avatar asked Sep 30 '22 18:09

David Gomez


1 Answers

I made it, I could make this simple animation work with JavaFX using this sprite image and I want to share with you in case you want to accomplish something similar

This is the result (YouTube)

First of all I created the FXML file for the login stage with this code (keep in mind that you have to set the correct location for your controller class and your image file)

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>

<GridPane alignment="CENTER" hgap="10.0" vgap="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="package.Controller">
    <padding>
        <Insets bottom="25.0" left="25.0" right="25.0" top="25.0" />
    </padding>
    <children>
        <ImageView fx:id="loginAnimationImageView" GridPane.columnIndex="0" GridPane.halignment="CENTER" GridPane.columnSpan="2" GridPane.rowIndex="0">
            <image>
                <Image url="@route/to/shop-sprite.png" />
            </image>
        <viewport>
            <Rectangle2D minX="0" minY="0" height="130.0" width="130.0" />
        </viewport>
        </ImageView>
        <Label text="Usuario" GridPane.columnIndex="0" GridPane.halignment="RIGHT" GridPane.rowIndex="2" />
        <TextField fx:id="loginTextField" onAction="#onEnterTextFieldAction" GridPane.columnIndex="1" GridPane.rowIndex="2" />
        <Label text="Contraseña" GridPane.columnIndex="0" GridPane.rowIndex="3" />
        <PasswordField fx:id="passwordTextField" onAction="#onEnterPasswordFieldAction" GridPane.columnIndex="1" GridPane.rowIndex="3" />
        <Button fx:id="loginButton" onAction="#loginButtonAction" text="Ingresar" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.rowIndex="5" />
    </children>
</GridPane>

Now we have to set our controller using the Animation Class created by Michael Heinrichs which I linked in the question above.

Note: this animation will be launch with the login button once the login and password information will be verified, so you have to set the code to accomplish this in your own app.

So here is the code for the controller:

public class MainController {
    private static final int COLUMNS  = 4;
    private static final int COUNT    = 12;
    private static final int OFFSET_X = 0;
    private static final int OFFSET_Y = 0;
    private static final int WIDTH    = 130;
    private static final int HEIGHT   = 130;
    @FXML private ImageView loginAnimationImageView;
    @FXML private TextField loginTextField;
    @FXML private PasswordField passwordTextField;
    @FXML private Button loginButton;

    @FXML protected void onEnterTextFieldAction(ActionEvent actionEvent) {
}

    @FXML protected void onEnterPasswordFieldAction(ActionEvent actionEvent) {
}

    @FXML protected void loginButtonAction(ActionEvent actionEvent) {
        final Animation animation = new SpriteAnimation(
                loginAnimationImageView,
                Duration.millis(400.0),
                COUNT, COLUMNS,
                OFFSET_X, OFFSET_Y,
                WIDTH, HEIGHT
        );

        animation.setCycleCount(1);
        animation.play();
    }
}

That's it, there's nothing else you have to do to create this simple animation for any of your JavaFX apps. Enjoy it!

like image 52
David Gomez Avatar answered Oct 06 '22 19:10

David Gomez