简体   繁体   English

JavaFX矩形圈出动画

[英]JavaFX Rectangle to circle animation

I have a rectangular pane that I'm using as a banner to hold icons vertically across the stage of my application for my home screen. 我有一个矩形窗格,用作标题,可以在应用程序的主屏幕上垂直放置图标。 Currently when I click on the icon I use a transition to slide the pane up (off screen), create a circle shape under the icon, and then move the icon and the circle together to the top right corner. 当前,当我单击图标时,我使用过渡将窗格向上滑动(屏幕外),在图标下创建一个圆形,然后将图标和圆圈一起移动到右上角。 Clicking on the icon in the corner reverses the animation and brings me back to my home screen. 单击角落的图标可以反转动画并使我回到主屏幕。

Instead of sliding my pane up I'd like to have my pane transform into this circle shape at where the Icon is. 我不想将窗格向上滑动,而是希望将窗格在“图标”所在的位置转换为该圆形。

I don't mind setting my pane to be transparent and creating a rectangle shape and then transform this rectangle to the circle - I think this is more doable. 我不介意将窗格设置为透明并创建一个矩形形状,然后将该矩形转换为圆形-我认为这更可行。

I haven't been able to find any clear example of transforming one shape to another though. 我还没有找到任何将一个形状转换为另一种形状的清晰示例。 I found this pretty good example, but it is for iOS: Circle to rectangle transformation animation 我发现了这个很好的示例,但它适用于iOS: 圆到矩形的转换动画

Any suggestions? 有什么建议么? I really only need a small example animation of turning a rectangle shape to a circle shape. 我真的只需要一个将矩形变成圆形的小动画示例。

Thanks! 谢谢!

Consider animating the clip of a region. 考虑为区域的片段设置动画。 You can combine this with a translation to move the "menu" to the top right. 您可以将其与翻译结合使用,以将“菜单”移至右上角。 Here is a simple example: 这是一个简单的示例:

import java.util.Random;

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import javafx.util.Duration;

public class AnimatingIconMenu extends Application {

    private BorderPane root ;

    @Override
    public void start(Stage primaryStage) {
        HBox menu = new HBox(10);
        BorderPane.setMargin(menu, new Insets(10));
        menu.setAlignment(Pos.CENTER);

        for (int i = 1; i <= 4 ; i++) {
            Option opt = new Option("Choice "+i);
            opt.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {

                Node view = opt.getView();
                Bounds b = view.getBoundsInParent();

                Rectangle clip = new Rectangle();
                Timeline timeline = new Timeline();
                Duration duration = Duration.seconds(0.66);

                if (isNowSelected) {

                    clip.setWidth(menu.getWidth());
                    clip.setHeight(menu.getHeight());

                    timeline.getKeyFrames().add(new KeyFrame(duration, 
                        new KeyValue(clip.xProperty(), b.getMinX()),
                        new KeyValue(clip.yProperty(), b.getMinY()),
                        new KeyValue(clip.widthProperty(), b.getWidth()),
                        new KeyValue(clip.heightProperty(), b.getHeight()), 
                        new KeyValue(clip.arcWidthProperty(), Math.min(b.getWidth(), b.getHeight())),
                        new KeyValue(clip.arcHeightProperty(), Math.min(b.getWidth(), b.getHeight())),
                        new KeyValue(menu.translateXProperty(), menu.getWidth() - b.getMaxX())));

                    timeline.setOnFinished(e -> showPage(opt));

                } else {

                    clip.setWidth(b.getWidth());
                    clip.setHeight(b.getHeight());
                    clip.setX(b.getMinX());
                    clip.setY(b.getMinY());
                    clip.setArcWidth(Math.min(b.getWidth(), b.getHeight()));
                    clip.setArcHeight(Math.min(b.getWidth(), b.getHeight()));

                    timeline.getKeyFrames().add(new KeyFrame(duration,
                        new KeyValue(clip.xProperty(), 0),
                        new KeyValue(clip.yProperty(), 0),
                        new KeyValue(clip.widthProperty(), menu.getWidth()),
                        new KeyValue(clip.heightProperty(), menu.getHeight()),
                        new KeyValue(clip.arcHeightProperty(), 0),
                        new KeyValue(clip.arcWidthProperty(), 0),
                        new KeyValue(menu.translateXProperty(), 0)));

                    timeline.setOnFinished(e -> showHome());
                }
                menu.setClip(clip);

                timeline.play();
            });
            menu.getChildren().add(opt.getView());
        }

        root = new BorderPane();
        showHome();
        root.setTop(menu);
        primaryStage.setScene(new Scene(root, 800, 600));
        primaryStage.show();

    }

    private void showPage(Option option) {

        Label label = new Label(option.getOptionText());
        label.setFont(Font.font("sans-serif", FontWeight.BOLD, 48));
        root.setCenter(label);
    }

    private void showHome() {
        Label label = new Label("Home");
        label.setFont(Font.font("sans-serif", FontWeight.BOLD, 48));
        root.setCenter(label);
    }

    public static class Option {

        private BooleanProperty selected = new SimpleBooleanProperty();

        private final String optionText ;
        private final Label view ;

        public Option(String optionText) {
            this.optionText = optionText ;
            this.view = new Label(optionText);
            view.setAlignment(Pos.CENTER);
            view.setWrapText(true);
            view.setPrefSize(80, 80);
            view.setStyle("-fx-background-color: -fx-background; -fx-background: "+randomColor()+";"); 
            view.setOnMouseClicked(e -> setSelected(!isSelected()));
        }

        public Node getView() {
            return view ;
        }

        public String getOptionText() {
            return optionText ;
        }

        private String randomColor() {
            Random rng = new Random();
            int r = rng.nextInt(256);
            int g = rng.nextInt(256);
            int b = rng.nextInt(256);
            return String.format("#%02x%02x%02x", r, g, b);
        }

        public final BooleanProperty selectedProperty() {
            return this.selected;
        }


        public final boolean isSelected() {
            return this.selectedProperty().get();
        }


        public final void setSelected(final boolean selected) {
            this.selectedProperty().set(selected);
        }


    }

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM