如何在JavaFX上为LinearGradient设置动画?

Mat*_*ari 2 java javafx javafx-2 javafx-8

我试图在JavaFX(使用JavaFX 8)上为Label的文本填充设置动画.我的目标是使渐变的第一种颜色每半秒从黄色变为红色.我试过这个:

Timeline timeline = new Timeline();
timeline.setCycleCount(Animation.INDEFINITE);
timeline.setAutoReverse(true);

LinearGradient fill1 = new LinearGradient(50,50,200,200,false, CycleMethod.NO_CYCLE, new Stop(0.1f, Color.YELLOW), new Stop(1.0f, Color.BLACK));
LinearGradient fill2 = new LinearGradient(50,50,200,200,false, CycleMethod.NO_CYCLE, new Stop(0.1f, Color.RED), new Stop(1.0f, Color.BLACK));
KeyValue keyValue1 = new KeyValue(labelInstrucoes.textFillProperty(), fill1, Interpolator.EASE_OUT);
KeyValue keyValue2 = new KeyValue(labelInstrucoes.textFillProperty(), fill2, Interpolator.EASE_OUT);

KeyFrame keyframe1 = new KeyFrame(Duration.millis(0), keyValue1);
KeyFrame keyframe2 = new KeyFrame(Duration.millis(500), keyValue2);

timeline.getKeyFrames().addAll(keyframe1, keyframe2);

timeline.play();
Run Code Online (Sandbox Code Playgroud)

但它没有用.但是,如果不使用LinearGradient,我会使用简单的颜色,如下所示:

KeyValue keyValue1 = new KeyValue(labelInstrucoes.textFillProperty(), Color.YELLOW, Interpolator.EASE_OUT);
KeyValue keyValue2 = new KeyValue(labelInstrucoes.textFillProperty(), Color.RED, Interpolator.EASE_OUT);
Run Code Online (Sandbox Code Playgroud)

有用.那么,如何为渐变设置动画?

Jam*_*s_D 7

您可以使用查找颜色使用css技巧.

在外部CSS文件中,为线性渐变的开头定义查找颜色,并使用引用查找颜色的线性渐变定义文本填充:

动画-gradient.css:

.animated-gradient {
    -gradient-base: red ;
    -fx-text-fill: linear-gradient(to right, -gradient-base, black);
}
Run Code Online (Sandbox Code Playgroud)

然后"动画化"颜色属性,并更新内联样式以在属性更改时更改查找颜色的值:

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;



public class AnimatedGradient extends Application {
    @Override
    public void start(Stage primaryStage) {
        StackPane root = new StackPane();
        Label label = new Label("Animated gradient");
        root.getChildren().add(label);
        label.getStyleClass().add("animated-gradient");
        Scene scene = new Scene(root,400,400);
        scene.getStylesheets().add(getClass().getResource("animated-gradient.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.show();

        ObjectProperty<Color> baseColor = new SimpleObjectProperty<>();

        KeyValue keyValue1 = new KeyValue(baseColor, Color.RED);
        KeyValue keyValue2 = new KeyValue(baseColor, Color.YELLOW);
        KeyFrame keyFrame1 = new KeyFrame(Duration.ZERO, keyValue1);
        KeyFrame keyFrame2 = new KeyFrame(Duration.millis(500), keyValue2);
        Timeline timeline = new Timeline(keyFrame1, keyFrame2);

        baseColor.addListener((obs, oldColor, newColor) -> {
            label.setStyle(String.format("-gradient-base: #%02x%02x%02x; ", 
                    (int)(newColor.getRed()*255),
                    (int)(newColor.getGreen()*255),
                    (int)(newColor.getBlue()*255)));
        });

        timeline.setAutoReverse(true);
        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.play();

    }

    public static void main(String[] args) {
        launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

(你可以使用Bindings.format(...)而不是听众,没有太大区别.)