有什么方法可以在JavaFX中实现此CSS动画?

时间:2020-11-12 12:22:14

标签: css javafx

HTML和CSS代码:

我从this post获得了这段代码

div {
    position: relative;
    display: inline-block;
    padding: 15px 70px;
    border: 5px solid #B17461;
    color: #B17461;
    font-size: 30px;
    font-family: arial;
    background-image: linear-gradient(#B17461, #B17461);
    background-position: 50% 50%;
    background-repeat: no-repeat;
    background-size: 0% 100%;
    transition: background-size .5s, color .5s;
  }
  div:hover {
    background-size: 100% 100%;
    color: #fff;
  }
<div>NEXT</div>

我想知道是否可以在JavaFX中实现此动画?我试过将进度条放在按钮后面,这两个按钮都包装在StackPane中。进度条的.track的背景色设置为透明,按钮的背景色设置为透明。但这似乎是一种低效的处理方式,并且说实话实现起来非常繁琐。那么还有其他更适合动画的方法吗?

2 个答案:

答案 0 :(得分:2)

这个简单的应用程序与您展示的几乎一样:

package example;

import javafx.animation.Animation;
import javafx.animation.Transition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.text.Font;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main extends Application {

    public static void main(String[] args) {
        launch(Main.class, args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        final Pane root = new Pane();
        // this color will be used for the Text-Color (not hovered), Border and the Background-Color (on hover)
        final Paint color = Color.web("#B17461");

        // basic stuff: text, font and text-color
        final Label label = new Label("NEXT");
        label.setFont(Font.font("Arial", 50.0));
        label.setTextFill(color);
        label.setTextAlignment(TextAlignment.CENTER);
        // same padding as you had
        label.setPadding(new Insets(15, 70, 15, 70));
        // border with the same settings as you had (5px solid)
        label.setBorder(new Border(new BorderStroke(color, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(5))));

        // maybe there's a better way to do this, but this one is the one I know. Simple Transition-Animation with a cycle of .5s
        // the interpolate-Method will be called by JavaFX on every frame with the current "progress" (from 0.0 to 1.0), so we simply calculate the background size in there
        final Animation animation = new Transition() {
            {
                setCycleDuration(Duration.millis(500L));
            }

            @Override
            protected void interpolate(double progress) {
                final double total = label.getWidth() / 2.0;
                final double current = (1.0 - progress) * total;

                label.setBackground(new Background(new BackgroundFill(color, CornerRadii.EMPTY, new Insets(0.0, current, 0.0, current))));
            }
        };

        // "hover": change text color and start the animation
        label.setOnMouseEntered(event -> {
            label.setTextFill(Color.web("#fff"));
            animation.playFromStart();
        });

        // "unhover": stop animation, reset background and text color
        label.setOnMouseExited(event -> {
            animation.stop();
            label.setBackground(null);
            label.setTextFill(color);
        });

      
        root.getChildren().add(label);

        stage.setScene(new Scene(root));
        stage.sizeToScene();
        stage.show();
    }
}

基本上,我只是在标签上以编程方式完成了CSS中的所有操作。 对于动画,我使用了简单的Transition和标签背景的Insets值。插图描述了背景不应该填充多少空间,就像填充一样,只填充背景。

答案 1 :(得分:1)

类似这样的事情,或者您可以对其进行修改以调整背景嵌入,例如codeflush.dev的答案...

public class Main extends Application {

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

    @Override
    public void start(Stage stage) throws Exception {
        Rectangle rect = new Rectangle(300, 30, Color.web("B17461"));
        rect.setScaleX(0);
        Button button = new Button("A Button");
        StackPane pane = new StackPane(rect, button);
        pane.setBackground(new Background(new BackgroundFill(Color.BLACK, CornerRadii.EMPTY, Insets.EMPTY)));

        TranslateTransition trans = new TranslateTransition(Duration.millis(500), rect);
        trans.setFromX(-150);
        trans.setToX(0);
        ScaleTransition scale = new ScaleTransition(Duration.millis(500), rect);
        scale.setFromX(0);
        scale.setToX(1);
        FillTransition fade = new FillTransition(Duration.millis(500), rect, Color.web("B17461"), Color.WHITE);
        Transition t = new ParallelTransition(trans, scale, fade);

        pane.setOnMouseEntered(me -> {
            t.stop();
            t.setRate(1);
            t.play();
        });
        pane.setOnMouseExited(me -> {
            t.stop();
            t.setRate(-1);
            t.play();
        });

        Scene scene = new Scene(pane);
        stage.setTitle("Transition");
        stage.setScene(scene);
        stage.setMinWidth(300);
        stage.setMinHeight(60);
        stage.show();
    }
}