当前位置: 首页 > 知识库问答 >
问题:

JavaFX:如何为窗格创建幻灯片动画效果(在透明舞台内)

陶星波
2023-03-14

我想要一些指导方针,如何实现一个幻灯片在过渡的窗格时,用户按下按钮,就像材料设计做它的滑动菜单。

这是一个视频链接,说明了我的需要。

我试过ScaleTransition,TranslateTransition,但他们没有成功。

// swipeMenuPane is builded in SceneBuilder and it is hidden,
// opacity = 0.0 and setX() = -getPrefWidth();
@FXML AnchorPane swipeMenuPane;
@FXML Button menuButton;

menuButton.setOnMouseClicked(e-> {
    swipeMenuPane.setOpacity(1.0);
    swipeTransition.play()
});

TranslateTransition swipeTransition = new TranslateTransition();
swipeTransition.setNode(swipeMenuPane);
swipeTransition.setDuration(Duration.millis(500));
swipeTransition.setToX(swipeMenuPane.getPrefWidth());

我想在用户单击按钮时缩小锚窗格。

我错过了什么?

package com.helloworld;

import com.gluonhq.charm.glisten.animation.ShrinkExpandAnimation;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class HelloWorld extends Application {

    ShrinkExpandAnimation anim;

    @Override
    public void start(Stage stage) {        
        Button btn = new Button("Click Me!");
        btn.setOnMouseClicked(e-> {
            System.out.println("swiping...");
            anim.play();
        });

        AnchorPane pane = new AnchorPane();
        pane.setStyle("-fx-background-color: coral");
        pane.getChildren().add(btn);

        // false to shrink or true to expand
        anim = new ShrinkExpandAnimation(pane, false);

        Scene scene = new Scene(new StackPane(pane), 640, 480);

        stage.setScene(scene);
        stage.show();
    }
}

---更新2---

    null

这是一个锚格(在其全宽处具有珊瑚色;展开)内的锚格(灰色的根格)。

这就是当你点击菜单按钮来缩小/隐藏它时会发生的情况。正如您所看到的,珊瑚色的窗格被缩小/隐藏了,但它的节点(标签、ImageView)没有缩小/隐藏

我发布了整个代码来重现您自己的问题:

public class SwipeMenuDemo extends Application {

    AnchorPane swapPane;
    Button btnMenu;
    boolean isExpanded = true;

    @Override
    public void start(Stage stage) {    
        Label swapPaneLabel = new Label("Expandable Pane");
        swapPaneLabel.setMinWidth(0);

        ImageView swapPaneImage = new ImageView("http://vignette1.wikia.nocookie.net/jfx/images/5/5a/JavaFXIsland600x300.png");
        swapPaneImage.setLayoutY(100);

        Label rootPaneLabel = new Label("Root Pane");
        rootPaneLabel.setStyle("-fx-font-size: 60;");
        rootPaneLabel.setLayoutX(180);
        rootPaneLabel.setLayoutY(180);

        swapPane = new AnchorPane();
        swapPane.setPrefSize(640, 440);
        swapPane.setMinWidth(0);
        swapPane.setLayoutY(40);
        swapPane.setStyle("-fx-background-color: coral; -fx-font-size: 52;");
        swapPane.getChildren().addAll(swapPaneImage, swapPaneLabel);

        btnMenu = new Button("Menu");
        btnMenu.setLayoutX(5);
        btnMenu.setLayoutY(5);
        btnMenu.setOnMouseClicked(e -> {
            if (isExpanded) hideSwapPane().play();
            else showSwapPane().play();
        });

        Button btnClose = new Button("Close");
        btnClose.setLayoutX(590);
        btnClose.setLayoutY(5);
        btnClose.setOnMouseClicked(e -> Platform.exit());

        AnchorPane rootPane = new AnchorPane();
        rootPane.setStyle("-fx-background-color: grey;");
        rootPane.getChildren().addAll(btnMenu, btnClose, rootPaneLabel, swapPane);

        Scene scene = new Scene(rootPane, 640, 480);

        stage.setScene(scene);
        stage.initStyle(StageStyle.UNDECORATED);
        stage.show();
    }

    private Animation hideSwapPane() {            
        btnMenu.setMouseTransparent(true);

        Animation collapsePanel = new Transition() {
            {
                setCycleDuration(Duration.millis(2500));
            }

            @Override
            protected void interpolate(double fraction) {
                swapPane.setPrefWidth(640 * (1.0 - fraction));
            }
        };

        collapsePanel.setOnFinished(e-> {
            isExpanded = false;
            btnMenu.setMouseTransparent(false);
        });

        return collapsePanel;
    }

    private Animation showSwapPane() {            
        btnMenu.setMouseTransparent(true);

        final Animation expandPanel = new Transition() {
            {
                setCycleDuration(Duration.millis(2500));
            }

            @Override
            protected void interpolate(double fraction) {
                swapPane.setPrefWidth(640 * fraction);
            }
        };

        expandPanel.setOnFinished(e-> {
            isExpanded = true;
            btnMenu.setMouseTransparent(false);
        });

        return expandPanel;
    }
}

这是我按下显示菜单,开始播放打开过渡时的“神器”……

我该怎么修好它?

共有1个答案

党祖鹤
2023-03-14

我是示例视频的作者。我将重复我在视频评论中所做的回应:“您应该将其视为android中的导航抽屉,JavaFX中的导航抽屉将是一个带有两个子的AnchorPane,首先是一个StackPane,它相当于一个FrameLayout作为我们的主要内容,其中窗格的转换取决于从左侧菜单中选择的项,最后是一个ListView作为我们的左侧菜单,它的负TranslateX的宽度等于ListView。然后,当用户按下按钮时,您必须播放一个将translatex的值写成0的动画。“您不应该在两个动画(折叠面板、展开窗格)的插值方法中使用prefwidth(),因为子动画不调整大小,边距排列是AnchorPane具有的唯一限制。

看看我做的这个例子。

https://github.com/marconideveloper/leftsideMenuexample

public class FXMLDocumentController implements Initializable {

    @FXML
    private Button menu;
    @FXML
    private AnchorPane navList;
    @Override
    public void initialize(URL url, ResourceBundle rb) {
    //navList.setItems(FXCollections.observableArrayList("Red","Yellow","Blue"));
        prepareSlideMenuAnimation();
    }    

    private void prepareSlideMenuAnimation() {
        TranslateTransition openNav=new TranslateTransition(new Duration(350), navList);
        openNav.setToX(0);
        TranslateTransition closeNav=new TranslateTransition(new Duration(350), navList);
        menu.setOnAction((ActionEvent evt)->{
            if(navList.getTranslateX()!=0){
                openNav.play();
            }else{
                closeNav.setToX(-(navList.getWidth()));
                closeNav.play();
            }
        });
    }
}

下面是FXML:

<AnchorPane xmlns:fx="http://javafx.com/fxml/1" id="AnchorPane" prefWidth="500" prefHeight="500"    fx:controller="leftslidemenusample.FXMLDocumentController">
    <children>

        <ToolBar AnchorPane.topAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" minHeight="56.0"   >
            <Button text="menu" fx:id="menu"  /> 
        </ToolBar>
        <StackPane fx:id="mainContent"  style="-fx-background-color:rgba(0,0,0,0.30)" AnchorPane.bottomAnchor="0.0" AnchorPane.topAnchor="56.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"    >
            <children>

            </children>
        </StackPane>
        <AnchorPane fx:id="navList" style="-fx-background-color:white" AnchorPane.topAnchor="56.0" AnchorPane.bottomAnchor="0.0" prefWidth="180.0" translateX="-180"   >
            <children>
                <Label text="left side menu"/>
            </children>
        </AnchorPane>

    </children>

</AnchorPane>
 类似资料:
  • 本文向大家介绍jquery带动画效果幻灯片特效代码,包括了jquery带动画效果幻灯片特效代码的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了jquery带动画效果幻灯片插件devrama.slider。分享给大家供大家参考。具体如下: jquery带动画效果幻灯片插件devrama.slider是一款可以在焦点图中嵌入html内容和文字动画效果,运行时可出现图文层叠显示效果,且图片下方伴

  • 我读过许多关于透明度和阴影的问题,但我认为我没有看到这个具体的问题得到解决。 我能够成功地创建一个既有透明度又有阴影的窗口,但我不知道如何使颜色阴影不影响透明度颜色。 例如,下面的代码创建了一个具有灰色透明度和红色阴影的窗口。然而,红色也影响了主窗口的透明度,但我只想让阴影延伸到窗口的边框之外。 我的测试代码:

  • 问题内容: 可以用幻灯片效果切换场景吗? 我希望当我在舞台实例上调用setScene时,它会以幻灯片效果更改场景。这是可能的? 问题答案: 您无法在两个场景之间应用过渡,因为不可能同时在一个舞台上同时使用这两个场景。一种解决方案是仅拥有一个场景并管理内部的所有过渡,如@James_D答案所示。 但是您也可以模拟两个场景之间的过渡。为此,您可以使用两个快照,在它们之间进行过渡,最后只设置新场景。 这

  • 问题内容: 我尝试创建简单的类,它可以像这样滑动JPanel: 我创建了javax.swing.Timer并添加到类中 这是工作,但是非常缓慢。我只有2-3 fps,并且不知道如何加快此方法的速度。你能帮我吗? 问题答案: 也许将计时器的间隔从50更改为较小的数字。 即从此: 对此: 注意:此处应避免使用幻数。 哎呀,像…

  • 我在“JavaFX:如何为窗格创建动画效果的幻灯片(在透明的舞台内)”上看到过这个问题。 我不明白约翰·阿斯特拉里迪斯最后一条评论中的部分代码。似乎解决了我的问题。我想滑动一个带有影子舞台的窗格。现在我的问题是幻灯片动画播放超出了我的视觉根窗格的限制,它只是与舞台(或实际根窗格)的限制播放。 我的可视根窗格是实际根窗格的子级,我用填充和corlor.transparent设置实际根窗格来实现我的可

  • 本文向大家介绍纯javascript移动优先的幻灯片效果,包括了纯javascript移动优先的幻灯片效果的使用技巧和注意事项,需要的朋友参考一下 简要教程 wallop是一款移动优先的纯javascript幻灯片插件。这个幻灯片插件仅4k大小,它的原理仅是为HTML元素添加和移除适当的class来显示和隐藏它们,至于这些class样式你可以完全自定义。特点有: 移动优先 动画和过渡效果都使用CS