【问题标题】:How to make an animation with CSS in JavaFX?如何在 JavaFX 中使用 CSS 制作动画?
【发布时间】:2013-07-14 14:50:05
【问题描述】:

我想通过更改样式类来更改Node 的样式。

Button button = new Button();
button.getStyleClass().add("class1")   
button.setOnMouseClicked(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent mouseEvent) {
            button.getStyleClass().add("class2");
        }
    });

是否可以逐渐改变样式,以制作类似过渡的东西?

【问题讨论】:

  • 除了您的问题:您为什么不在示例代码中使用花哨的 Lambda 注释?而不是 (new Eventhan...) 您只需编写:mouseEvent -> button.getStyleClass().add("class2")。喜欢吗?

标签: animation user-interface javafx-2 javafx-8


【解决方案1】:

是否可以逐渐改变风格,例如做一些过渡?

是的。

您将需要使用 setStyle 而不是样式类,因为类将是在 css 中定义的静态事物。 JavaFX css 中没有对动画的直接支持。您需要在 Java 代码中执行动画步骤来修改 css 样式。

我只在您想使用 css 执行转换时才真正推荐这种方法,因为没有容易获得的相应 Java API。

要处理动画,您可以使用标准的 javafx 动画Timeline 来操作 css 样式属性所依赖的属性。

例如,将您的样式属性绑定到字符串。然后在时间轴中改变您想要更改的组件(在本例中为 colorStringProperty)。

warningButton.styleProperty().bind(
    new SimpleStringProperty("-fx-base: ")
        .concat(colorStringProperty)
        .concat(";")
        .concat("-fx-font-size: 20px;")
);

这是一个示例,它使用 css 闪烁按钮,按下时其基色从灰色到红色逐渐过渡。

import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.beans.value.*;
import javafx.event.*;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.*;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;

/** Shows how you can modify css styles dynamically using a timeline. */
public class Warning extends Application {

    private static final String BACKGROUND = "http://bobgreiner.tripod.com/1cc2ce10.jpg"; 

    @Override
    public void start(Stage stage) throws Exception{
        final ObjectProperty<Color> warningColor = new SimpleObjectProperty<>(Color.GRAY);
        final StringProperty colorStringProperty = createWarningColorStringProperty(warningColor);

        StackPane layout = new StackPane();
        layout.getChildren().addAll(
                new ImageView(new Image(BACKGROUND)),
                createWarningButton(
                        warningColor, 
                        colorStringProperty
                )
        );
        stage.setScene(new Scene(layout));
        stage.show();
    }

    private StringProperty createWarningColorStringProperty(final ObjectProperty<Color> warningColor) {
        final StringProperty colorStringProperty = new SimpleStringProperty();
        setColorStringFromColor(colorStringProperty, warningColor);
        warningColor.addListener(new ChangeListener<Color>() {
            @Override
            public void changed(ObservableValue<? extends Color> observableValue, Color oldColor, Color newColor) {
                setColorStringFromColor(colorStringProperty, warningColor);
            }
        });

        return colorStringProperty;
    }

    private Button createWarningButton(final ObjectProperty<Color> warningColor, StringProperty colorStringProperty) {
        final Button warningButton = new Button("Warning! Warning!");
        warningButton.styleProperty().bind(
                new SimpleStringProperty("-fx-base: ")
                        .concat(colorStringProperty)
                        .concat(";")
                        .concat("-fx-font-size: 20px;")
        );

        warningButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent actionEvent) {
                Timeline flash = new Timeline(
                    new KeyFrame(Duration.seconds(0),    new KeyValue(warningColor, Color.GRAY, Interpolator.LINEAR)),
                    new KeyFrame(Duration.seconds(0.25), new KeyValue(warningColor, Color.GRAY, Interpolator.LINEAR)),
                    new KeyFrame(Duration.seconds(1),    new KeyValue(warningColor, Color.RED,  Interpolator.LINEAR)),
                    new KeyFrame(Duration.seconds(1.25), new KeyValue(warningColor, Color.RED,  Interpolator.LINEAR))
                );
                flash.setCycleCount(6);
                flash.setAutoReverse(true);
                flash.play();
            }
        });

        return warningButton;
    }

    private void setColorStringFromColor(StringProperty colorStringProperty, ObjectProperty<Color> color) {
        colorStringProperty.set(
                "rgba("
                        + ((int) (color.get().getRed()   * 255)) + ","
                        + ((int) (color.get().getGreen() * 255)) + ","
                        + ((int) (color.get().getBlue()  * 255)) + ","
                        + color.get().getOpacity() +
                ")"
        );
    }

    public static void main(String[] args) {
        launch(args);
    }
}

【讨论】:

    【解决方案2】:

    JavaFX2 支持转换。所以你不需要一步一步制作动画。

    看看这个: http://docs.oracle.com/javafx/2/animations/basics.htm#CJAJJAGI

    【讨论】:

    • 他问的是 CSS 动画而不是程序化动画
    • 我知道。 Jewelsea 提到,JavaFX 不支持 CSS 动画,需要执行单个动画步骤。我只是想澄清一下,如果您使用转换,这不是必需的。
    猜你喜欢
    • 2020-05-14
    • 2022-12-16
    • 2022-01-07
    • 2017-07-04
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    • 2019-06-16
    相关资源
    最近更新 更多