JavaFX animação de "sumir para esquerda"

11 respostas Resolvido
javafx
Thallysson

Olá. Eu criei uma tela de notificações em JavaFX, tudo funciona perfeitamente, aqui está o método de criação das notificações:

public void showSimpleNotification(String message, ImageView icon, boolean alwaysOnTop){
	HBox h = new HBox();
	h.setAlignment(Pos.CENTER_LEFT);
	h.getChildren().add(icon);
	h.getChildren().add(new Label("Message"));
	if(!alwaysOnTop){
		AnchorPane anch = new AnchorPane();
		Button bt = new Button();
		bt.setGraphic(new ImageView(new Image(getClass().getResourceAsStream("/icons/cancel.png"))));
		bt.setOnAction((ActionEvent) ->{
			desktop.getChildren().remove(h);
		});
		bt.getStyleClass().add("button-with-icon");
		anch.getChildren().add(bt);
		anch.setRightAnchor(bt, 0.14);
		anch.setTopAnchor(bt, 0.14);
		h.getChildren().add(anch);
	}
	h.getStyleClass().add("notification");
	h.setAlignment(Pos.CENTER_LEFT);
	HBox.setHgrow(h.getChildren().get(0), Priority.SOMETIMES);
	HBox.setHgrow(h.getChildren().get(1), Priority.ALWAYS);
	HBox.setHgrow(h.getChildren().get(2), Priority.SOMETIMES);
	desktop.getChildren().add(h);
}

Porém eu gostaria de fazer com que antes de remover do desktop a notificação fizesse aquela animação de “ir para a esquerda” como no Android por exemplo. Alguém sabe se isso seria possível?

11 Respostas

J

Olá Amigo
Tem Um Cana no youtube chamado Genuine Coder, ele fala tudo sobre isso
Da uma olhada la o link é: https://www.youtube.com/channel/UCCXbhmjID-T2I0KfuDPbi6A
Se ele não tiver um video ensinando direto como você faz, com outros videos você vai pegar uma base, como a tela de notificações que ele fez, é bem legal!

Espero ter ajudado, qualquer coisa me chame :slight_smile:

Thallysson

Valeu pela dica, é um canal bem bacana, eu vou procurar na playlist de animation e ver se encontro uma solução por lá.

J

Nada amigo, Disponha

Andrauss
Solucao aceita

Aprendi muito sobre animações aqui: https://github.com/fxexperience/code/tree/master/FXExperienceControls/src/com/fxexperience/javafx/animation

Veja a classe fadeoutlefttransition.java.

Para usar:
new FadeOutLeftTransition(node).play();

Aviso.: A classe TimelineBuilder está depreciada use o construtor da classe Timeline e passe os keyframes.

Isso também ajuda a entender como funciona: http://docs.oracle.com/javafx/2/animations/basics.htm

Thallysson

Nunca pensei que fosse tão simples, eu implementei, aparentemente está funcionando, porém está MUITO rápido. Eu já alterei todas as propriedades de mile segundos que eu vi na classe mas continua rápido, mas rápido que não dá nem pra perceber a animação.

Andrauss

Já tentou a propriedade Duration? Ou melhor CycleDuration

Thallysson

Até com valores altos como esses eu não consigo visualizar a animação:

setCycleDuration(Duration.seconds(5));
    setDelay(Duration.seconds(2.0));
Andrauss

Explicando:
Delay é o tempo de espera para executar a animação.
Duration é o tempo de execução da animação.

Você deve ter alterado os keyframes.

Thallysson

Mas mesmo alterando o Duration eu não consigo ver a diferença. Agora eu percebi que eu estava utilizando o exemplo do FadeInleftTransition ao invés de FadeOutLeftTransition, porém dá na mesma depois de mudar.

Estou implementando assim:

bt.setOnAction((ActionEvent) ->{
			new FadeOutLeftTransition(h).play();
			desktop.getChildren().remove(h);
		});

A classe:

import com.gluonhq.charm.glisten.animation.CachedTimelineTransition;

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.scene.Node;
import javafx.util.Duration;

/**
 * Animate a fade out left effect on a node
 * 
 * Port of FadeOutLeft from Animate.css http://daneden.me/animate by Dan Eden
 * 
 * {@literal @}keyframes fadeOutLeft {
 * 	0% {
 * 		opacity: 0;
 * 		transform: translateX(0);
 * 	}
 * 	100% {
 * 		opacity: 1;
 * 		transform: translateX(-20px);
 * 	}
 * }
 * 
 * @author Jasper Potts
 */
public class FadeOutLeftTransition extends CachedTimelineTransition {
    /**
     * Create new FadeOutLeftTransition
     * 
     * @param node The node to affect
     */
    public FadeOutLeftTransition(final Node node) {
        super(
            node,
            new Timeline(
        		new KeyFrame(Duration.millis(0),    
                        new KeyValue(node.opacityProperty(), 1, WEB_EASE),
                        new KeyValue(node.translateXProperty(), 0, WEB_EASE)
                    ),
                    new KeyFrame(Duration.millis(1000),    
                        new KeyValue(node.opacityProperty(), 0, WEB_EASE),
                        new KeyValue(node.translateXProperty(), -20, WEB_EASE)
                    )
                ));
        setCycleDuration(Duration.seconds(3));
        setDelay(Duration.seconds(0.2));
    }
    
    @Override protected void stopping() {
        super.stopping();
        node.setTranslateX(0); // restore default
    }
}

Resultado:

Andrauss

A animação é executada em background, quando vc remove o node do pane a animação continua rodando mas vc não vê. Faça o seguinte:
Adicione uma ação para quando a animação terminar com setOnFinished, essa ação deve ser remover o componente. Isso resolve.

Thallysson

Muito obrigado pela ajuda, está funcionando:

FadeOutLeftTransition f = new FadeOutLeftTransition(h);
f.play();
f.setOnFinished(new EventHandler<ActionEvent>() {
    @Override
    public void handle(javafx.event.ActionEvent arg0) {
    	desktop.getChildren().remove(h);
    }
});
Criado 5 de março de 2017
Ultima resposta 6 de mar. de 2017
Respostas 11
Participantes 3