Я ранее опубликовал вопрос о том, почему анимация наложения в контейнере StackPane происходит мгновенно при использовании ключа. Они выполняются один раз в конце продолжительности кадра. They do not cause the value to change incrementally over time.
And to solve it:
For that, pass a KeyValue when creating the KeyFrame
He also suggested reading his answer to a previously posted Вопрос, объясняя, как следует обрабатывать сходные анимации.
Решение
Следующее @Slaw, ответ: CodationAnimation класс обрабатывает наложение и Iconlabel анимации, соответственно, с использованием параллельсза PREARGACKWARD () Обрабатывает оба события mouse_entered mouse_exited
проблема
createTobottOmanimation () возвращает временную шкалу для перехода на наложение. Когда ключевые кадры до значения жестко кодируются (например, 200), анимация происходит гладко, а максимальная высота постепенно обновляется. Тем не менее, проблема заключается в том, что при изменении размера окна наложение не заполнит весь свой контейнер, поскольку его родительский увеличился, а значение жестко кодируется. Оверлей сейчас заполняет свой контейнер, но не происходит анимации
code
import javafx.animation.*;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.Objects;
public class Example extends Application {
private ImageView createImageIcon(String path) {
Image image = new Image(Objects.requireNonNull(getClass().getResourceAsStream(path)));
ImageView imageView = new ImageView(image);
imageView.setPreserveRatio(true);
imageView.setFitHeight(200);
imageView.setFitWidth(200);
return imageView;
}
private Pane crateImageIconContainer(ImageView image, VBox overlay, String iconTitle, HBox rootElement) {
Pane region = new Pane();
HBox.setMargin(region, new Insets(30, 30, 30, 30));
region.maxWidthProperty().bind(rootElement.widthProperty().divide(3));
region.maxHeightProperty().bind(region.widthProperty());
region.setPrefSize(400, 400);
StackPane stackableContainer = new StackPane();
HBox.setMargin(stackableContainer, new Insets(30, 30, 30, 30));
stackableContainer.prefWidthProperty().bind(region.widthProperty());
stackableContainer.prefHeightProperty().bind(region.heightProperty());
stackableContainer.setStyle("-fx-background-color: #ff0000;");
region.getChildren().add(stackableContainer);
image.fitWidthProperty().bind(stackableContainer.widthProperty().divide(1.5));
image.fitHeightProperty().bind(stackableContainer.heightProperty().divide(1.5));
Label iconLabel = new Label(iconTitle);
iconLabel.setOpacity(0);
overlay.getChildren().add(iconLabel);
overlay.setAlignment(Pos.CENTER);
StackPane.setAlignment(overlay, Pos.TOP_CENTER);
overlay.setStyle("-fx-background-color: #ffffff;");
overlay.setOpacity(0.8);
overlay.setMaxHeight(0);
stackableContainer.getChildren().addAll(image, overlay);
var animation = new OverLayAnimation(overlay, iconLabel);
stackableContainer.addEventHandler(MouseEvent.MOUSE_ENTERED, e -> {
e.consume();
animation.playForward();
});
stackableContainer.addEventHandler(MouseEvent.MOUSE_EXITED, e -> {
e.consume();
animation.playBackward();
});
return region;
}
@Override
public void start(Stage primaryStage) throws Exception {
HBox mainContainer = new HBox();
HBox.setHgrow(mainContainer, Priority.ALWAYS);
mainContainer.setAlignment(Pos.CENTER);
mainContainer.setStyle("-fx-background-color: #00396c;");
ImageView photoIcon = createImageIcon("../resources/photo.png");
ImageView videoIcon = createImageIcon("../resources/video.png");
ImageView webCamIcon = createImageIcon("../resources/webcam.png");
Pane photoIconContainer = crateImageIconContainer(photoIcon, new VBox(), "Photo", mainContainer);
Pane videoIconContainer = crateImageIconContainer(videoIcon, new VBox(), "Video", mainContainer);
Pane webCamIconContainer = crateImageIconContainer(webCamIcon, new VBox(), "Web Cam", mainContainer);
mainContainer.getChildren().addAll(photoIconContainer, videoIconContainer, webCamIconContainer);
Scene scene = new Scene(mainContainer, 900, 350);
primaryStage.setTitle("Color isolator");
primaryStage.setScene(scene);
primaryStage.show();
}
private static class OverLayAnimation {
private final VBox overlay;
private final Label iconLabel;
private static final Duration DURATION = Duration.millis(350);
private final ParallelTransition transition;
OverLayAnimation(VBox overlay, Label iconLabel) {
this.overlay = overlay;
this.iconLabel = iconLabel;
var toBottom = createToBottomAnimation();
var fadeInOut = createFadeInAndOutAnimation();
transition = new ParallelTransition(toBottom, fadeInOut);
}
void playForward() {
transition.setRate(1);
transition.play();
}
void playBackward() {
// Does not execute
// transition.setRate(-1);
// transition.play();
KeyValue x = new KeyValue(overlay.maxHeightProperty(), 0);
KeyFrame frame = new KeyFrame(DURATION, x);
Timeline timeline = new Timeline(frame);
timeline.play();
}
private Animation createToBottomAnimation() {
// Animate instantly
KeyValue x = new KeyValue(overlay.maxHeightProperty(), ((Pane) overlay.getParent()).getMaxHeight());
// Animate smoothly
// KeyValue x = new KeyValue(overlay.maxHeightProperty(), 200);
KeyFrame frame = new KeyFrame(DURATION, x);
return new Timeline(frame);
}
private Animation createFadeInAndOutAnimation() {
var fadeInOut = new FadeTransition(DURATION, iconLabel);
fadeInOut.setFromValue(0);
fadeInOut.setToValue(1);
return fadeInOut;
}
}
}
< /code>
Результаты < /h2>
Так выглядит мгновенная анимация. И вот как должна выглядеть анимация, но, поскольку значение для 200, она не заполнит контейнер.>
Подробнее здесь: https://stackoverflow.com/questions/797 ... s-the-targ