IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo

FAQ JavaFXConsultez toutes les FAQ

Nombre d'auteurs : 4, nombre de questions : 507, dernière mise à jour : 2 novembre 2016  Ajouter une question

 

Cette FAQ a été réalisée à partir des questions fréquemment posées sur le forum JavaFX de http://java.developpez.com ainsi que l'expérience personnelle des auteurs.

Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.

Sur ce, nous vous souhaitons une bonne lecture.

SommaireSceneGraphAnimations (28)
précédent sommaire suivant
 

Les animations sont construites à partir de la classe javafx.animation.Animation et de ses classes filles présentes dans le package javafx.animation.

Il existe deux manières de faire des animations en JavaFX :

  • Timeline - une ligne de temps ou ligne temporelle constituée d’étapes-clés (key frames). L'animation doit être construite ici de manière manuelle ;
  • Transition - une animation prête à l'emploi qui peut utiliser directement les propriétés d'un nœud.


Les deux types d'animations peuvent être utilisés ensemble.

Mis à jour le 9 septembre 2014 bouye

Nous devons utiliser la classe javafx.util.Duration pour spécifier des durées ou des instants/moments dans le temps qui serviront à définir des étapes-clés dans les animations.

La classe Duration dispose de constantes statiques prêtes à l'emploi ainsi que de méthodes de fabriques statiques qui permettent de convertir des valeurs numériques en durées. Des méthodes utilitaires d'instance sont également disponibles pour convertir une durée en valeur numérique ou effectuer des opérations arithmétiques entre durées. Ce type n'a pas d'équivalent dans le langage Java 7 ou moins et s'apparente à la classe java.time.Duration disponible en Java 8 ou ultérieure.

Code Java : Sélectionner tout
1
2
3
final Duration d100ms = Duration.millis(100); // Une durée de 100 millisecondes. 
final Duration d5m = Duration.minutes(5); // Une durée de 5 minutes. 
System.out.printf("%f s", d100ms.toSeconds()).println(); // Imprime la valeur de 100ms en secondes.

Les durées ainsi créées sont indépendantes de la notion de calendrier.

Mis à jour le 9 septembre 2014 bouye

Il suffit d'appeler la méthode playFromStart() de l'animation. L'animation démarrera à partir de son temps initial (Duration.ZERO) et s'effectuera dans le sens positif (sens de temps croissant) tout en conservant le rythme précédemment défini.

Code Java : Sélectionner tout
animation.playFromStart()

Appeler cette méthode est l’équivalent d’exécuter le code suivant :

Code Java : Sélectionner tout
1
2
3
4
animation.stop(); 
animation.setRate = setRate(Math.abs(animation.getRate()));  
animation.jumpTo(Duration.ZERO); 
animation.play();

On peut donc utiliser cette méthode pour relancer complètement une animation en cours ou déjà terminée.

Mis à jour le 9 septembre 2014 bouye

Il suffit d'utiliser la méthode playFrom() de l'animation en spécifiant le temps de départ.

Code Java : Sélectionner tout
animation.playFrom(Duration.millis(750));

Mis à jour le 9 septembre 2014 bouye

Il suffit d'appeler la méthode stop() de l'animation. Cette méthode positionne le curseur de temps de l'animation à sa position initiale. Appeler cette méthode n'a aucun effet si l'animation n'est pas en train d’être jouée.

Code Java : Sélectionner tout
animation.stop();

Mis à jour le 9 septembre 2014 bouye

Il suffit d'appeler la méthode pause() de l'animation. Cette méthode conserve le curseur de temps de l'animation à sa position actuelle. Appeler cette méthode n'a aucun effet si l'animation n'est pas en train d’être jouée.

Code Java : Sélectionner tout
animation.pause();

Mis à jour le 9 septembre 2014 bouye

Il suffit d'appeler sa méthode play() de l'animation. L'animation reprendra à partir du point où elle s'est précédemment arrêtée. Si elle n'a jamais été lancée précédemment, elle démarrera au temps initial de la ligne temporelle (Duration.ZERO).

Code Java : Sélectionner tout
animation.play()

Mis à jour le 9 septembre 2014 bouye

Il est possible de modifier la vitesse d'une animation en modifiant sa propriété rate.

Code Java : Sélectionner tout
animation.setRate(2);

Pour doubler la vitesse d'une animation, il suffit de la mettre à 2.

Code Java : Sélectionner tout
animation.setRate(0.5);

Pour ralentir une animation de moitié, il suffit de la mettre à 0.5.

Par défaut, la propriété rate a une valeur égale à 1.

Mis à jour le 9 septembre 2014 bouye

Pour inverser une animation, il suffit de lui donner une valeur négative pour sa propriété rate. L'animation ira alors à rebours depuis son emplacement actuel dans la ligne temporelle.

Code Java : Sélectionner tout
animation.setRate(-1);

Mis à jour le 9 septembre 2014 bouye

Il faut utiliser la méthode jumpTo() de l’animation en spécifiant une Duration en paramètre.

Code Java : Sélectionner tout
animation.jumpTo(Duration.seconds(5));

Mis à jour le 9 septembre 2014 bouye

Pour spécifier le nombre de répétitions d'une animation, il faut modifier la valeur de la propriété cycleCount de l'animation en spécifiant le nombre de boucles désirées par un nombre entier. Si la valeur est égale à 1, l'animation s'exécutera une seule et unique fois. Pour répéter l'animation indéfiniment, il faut utiliser la valeur Timeline.INDEFINITE.

Code Java : Sélectionner tout
animation.setCycleCount(10);

Par défaut, la propriété cycleCount a une valeur de 1.

Mis à jour le 9 septembre 2014 bouye

Pour inverser une animation automatiquement quand elle se répète, il faut modifier la valeur de sa propriété autoReverse et la mettre à la valeur true. Si l'animation se répète plus d'une fois, la vitesse de lecture se verra inversée à chaque fois qu'elle arrive à une extrémité de sa ligne temporelle.

Code Java : Sélectionner tout
animation.setAutoReverse(true);

Par défaut, la propriété autoReverse est à la valeur false.

Mis à jour le 9 septembre 2014 bouye

Un interpolateur est un objet de type javafx.animation.Interpolator qui permet de modifier l’évolution d'une valeur entre deux étapes-clés. Pour être plus précis, il permet de modifier la vitesse à la laquelle la valeur part de la valeur initiale pour arriver à la valeur finale. Graphiquement, cela peut se traduire par exemple lorsque la vitesse de déplacement, de rotation ou d'agrandissement du nœud en train d’être animé varie au cours du temps.

Par défaut, l'API d'animation JavaFX fournit cinq types d'interpolateurs :

  • Interpolator.DISCRETE - la valeur conserve sa valeur initiale durant toute l'animation. À la fin de l'animation, elle passe à la valeur finale
  • Interpolator.LINEAR - durant toute l'animation, la valeur évolue à vitesse constante depuis la valeur initiale jusqu’à la valeur finale
  • Interpolator.EASE_IN - l'animation démarre lentement, puis gagne en vitesse, et, au bout d'un certain temps, la valeur évolue à vitesse constante jusqu’à la valeur finale
  • Interpolator.EASE_OUT - durant l'animation, la valeur évolue à vitesse constante depuis la valeur initiale jusqu’à un certain point. Passé cet instant, la vitesse d’évolution ralentit jusqu’à atteindre la valeur finale de l'animation
  • Interpolator.EASE_BOTH - une combinaison de EASE_IN et EASE_OUT. L'animation démarre et se termine lentement tandis que la partie centrale se déroule à vitesse constante

Mis à jour le 9 septembre 2014 bouye

Vous pouvez directement étendre la classe javafx.animation.Interpolator et surcharger la méthode curve() pour créer de nouveaux types d'interpolateurs.

Prenons par exemple le code suivant :

Code Java : Sélectionner tout
1
2
3
4
5
6
new Interpolator() { 
    @Override 
    protected double curve(double t) { 
        return (1 - Math.sin(Math.PI / 2d + t * Math.PI)) / 2d; 
    } 
}

Ce qui nous donne une courbe sinusoïdale d'une demi-phase :



Ici, notre interpolateur se comporte comme Interpolator.EASE_BOTH, mais sans passer par une vitesse constante durant l'animation. En suivant la courbe sinusoïdale, l’évolution de la valeur démarre lentement puis augmente en vitesse jusqu’à la moitié de l'animation puis, décélère jusqu’à atteindre la valeur finale.

Prenons maintenant le code suivant :

Code Java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
new Interpolator() { 
    private double factor = 1.25; 
    private final double min = 0; 
    private final double max = (1 - Math.sin(Math.PI / 2d + factor * Math.PI)) / 2d; 
  
    @Override 
    protected double curve(double t) { 
        double sin = Math.sin(Math.PI / 2d + t * factor * Math.PI); 
        sin = (1 - sin) / 2d; 
        sin = sin / (max - min); 
        return sin; 
    } 
}

À nouveau nous avons une courbe sinusoïdale, mais ici la phase est légèrement décalée ; l'ensemble de l'animation fait un peu plus d'une demi-phase sinusoïdale :



Imaginons maintenant que nous voulions faire une animation de changement d’échelle sur une image pour faire une animation de type spring (ressort) comme sur plateformes web et mobiles pour donner l'impression qu'elle jaillit au visage de l'utilisateur :

  • initialement l'image est à sa (petite) taille d'origine ;
  • l'image commence à s'agrandir lentement, puis le changement de taille s’accélère ;
  • le changement de taille commence à ralentir, l'image approche de sa taille finale ;
  • la taille de l'image dépasse la taille finale escomptée tout en continuant à ralentir ;
  • puis elle finit par marquer un palier à une taille qui est un peu plus grande que celle que nous voulions atteindre ;
  • le changement de taille s'inverse et l'image commence à rétrécir, d'abord lentement puis en accélérant ;
  • l'animation s’arrête lorsque l'image atteint une seconde fois sa taille de destination.


Ceci n'est qu'un exemple, on pourrait encore faire beaucoup de types d'animation différents uniquement en modifiant la phase, le nombre de phases, l'amplitude de la courbe ou encore la longueur d'onde de la courbe sinusoïdale...

Mis à jour le 9 septembre 2014 bouye

La classe javafx.animation.AnimationTimer (littéralement « minuteur d'animation») permet d'utiliser un timer de granularité fine qui tourne sur le thread des animations et donc aux alentours de 60 fps (60 images par seconde. Ici, image = pulsation ou impulsion du timer ; on dit également un pulse).

Ce genre de minuteur peut être utilisé pour gérer des animations sans passer par des instances des classes Timeline ou Transition, par exemple pour gérer une fontaine à particules pour laquelle utiliser une classe d'animation classique ne serait pas efficace.

Ce minuteur peut également être utilisé pour des travaux sans rapport direct avec un affichage : un timer qui met à jour le « monde » d'un jeu côté serveur (indépendamment de la sortie graphique donc).

Mis à jour le 15 mars 2015 bouye

Pour utiliser la classe AnimationTimer, vous devez en créer une nouvelle instance et surcharger sa méthode handle(). Cette méthode est invoquée à chaque pulsation du timer et reçoit en paramètre, le temps actuel en nanosecondes. Vous pouvez alors effectuer vos travaux graphiques ou non dans le corps de cette méthode.

Vous pouvez ensuite invoquer la méthode start() de la classe AnimationTimer pour démarrer le minuteur et il vous suffira d'invoquer sa méthode stop() pour l’arrêter.

Par exemple, le code suivant permet de vérifier que le timer tourne aux alentours de 60 fps en calculant le temps moyen entre deux pulsations et en affichant le résultat dans un label dans la scène :

Code Java : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
public class Main extends Application { 
  
    private Label label; 
    private ToggleButton button; 
    private AnimationTimer timer; 
  
    @Override 
    public void start(Stage primaryStage) { 
        label = new Label(); 
        StackPane.setAlignment(label, Pos.TOP_LEFT); 
        button = new ToggleButton("Lancement"); 
        button.setOnAction(actionEvent -> toggleTimer()); 
        final StackPane root = new StackPane(); 
        root.getChildren().setAll(button, label); 
        final Scene scene = new Scene(root, 350, 300); 
        primaryStage.setTitle("Test du minuteur d'animation"); 
        primaryStage.setScene(scene); 
        primaryStage.show(); 
    } 
  
    private void toggleTimer() { 
        if (timer == null) { 
            timer = new AnimationTimer() { 
                private final int MAXSAMPPLES = 100; 
                private long[] diffs = new long[MAXSAMPPLES]; 
                private long previousTime = -1; 
                private int currentIndex = 0; 
  
                @Override 
                public void handle(long now) { 
                    if (previousTime != -1) { 
                        diffs[currentIndex] = now - previousTime; 
                        currentIndex++; 
                    } 
                    if (currentIndex == MAXSAMPPLES) { 
                        long sum = 0; 
                        for (int index = 0; index < MAXSAMPPLES; index++) { 
                            sum += diffs[index]; 
                        } 
                        double average = sum / (double) MAXSAMPPLES; 
                        average /= (1000.0 * 1000.0 * 1000.0); 
                        average = 1 / average; 
                        label.setText(String.format("%.1f", average)); 
                        currentIndex = 0; 
                    } 
                    previousTime = now; 
                } 
            }; 
            timer.start(); 
            button.setText("Arrêt"); 
        } else { 
            timer.stop(); 
            timer = null; 
            button.setText("Lancement"); 
        } 
    } 
  
    public static void main(String[] args) { 
        launch(args); 
    } 
}

Mis à jour le 15 mars 2015 bouye

Proposer une nouvelle réponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.