2016-09-26 118 views
2

我有一个矩形窗格,我用它作为横幅在我的主屏幕的应用程序的舞台上垂直放置图标。目前,当我点击图标时,我使用了一个转换来将窗格向上(离屏)滑动,在图标下创建一个圆形,然后将图标和圆圈一起移动到右上角。点击角落中的图标可反转动画并将我带回我的主屏幕。JavaFX用于圆形动画的矩形

不是将我的窗格向上滑动,而是想让我的窗格转换成此图标所在的圆形。

我不介意将我的窗格设置为透明并创建矩形形状,然后将此矩形转换为圆形 - 我认为这更可行。

我还没有找到任何将一个形状转换为另一个形状的清晰示例。我发现这个很不错的例子,但它适用于iOS:Circle to rectangle transformation animation

有什么建议吗?我真的只需要一个将矩形形状变成圆形的小例子动画。

谢谢!

+0

'“你想同时按比例增加和圆角半径减小到在同一时间发生。”'Citated从后你提供。那么确切的问题是什么?您一般会在javafx中计算动画,您知道要修改哪些属性,是否有更多要求开始? – n247s

回答

5

考虑动画区域的剪辑。您可以将其与翻译结合使用,将“菜单”移动到右上角。下面是一个简单的例子:

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); 
    } 
}