2017-01-16 1 views
1

javafx에서 usercontrol의 회전에 문제가 있습니다. 내 설정은 다음과 같습니다 :javafx에서 X 축 위에 스크롤 패널 회전 - 효과와 같은 스타 워브

센터에 400x600 스크롤 패널 인 scrollpane이 있고 나중에 텍스트가있는 레이블 목록이 들어있는 vbox로 동적으로 채워진 장면이 있습니다.

내가하고 싶은 일은이 패널에 회전을 추가하여 스타 워즈 소개 텍스트처럼 보이게하는 것입니다. 나는 텍스트를 스크롤하는 애니메이션을 얻을 수 있었지만, X_AXIS를 통해 패널을 회전 시키려고 할 때, 나는 원하는대로하지 않을 것이다.

목표 : Panel that is rotated as if it was this text 현재 My best attempt after spending hours transforming

:

scrollpane.getTransforms().add(new Rotate(50, 300, 200, 20, Rotate.X_AXIS)); 

당신이 텍스트는 적절한 각도를 대상으로 볼 수 있지만 컨트롤 자체가 실제로 X 축 이상 회전 3D 아니므로. 현재 원하는 효과를 얻으려면 무엇을 추가해야합니까? (절대 픽셀의 패널 상단이 하단보다 넓지 않음)

+0

당신은 두 가지 속성, 이탤릭 형식과 확대가 필요) 텍스트가 당신의 '가 ScrollPane'가 그것을 가져 작고은 가까이의 상단에있는 가까운 그것은 더 큰 부분에 도달하게됩니다. –

+1

원근감 변환 효과를 적용하면 효과가 있습니다. [PerspectiveTransform] (https://docs.oracle.com/javafx/2/api/javafx/scene/effect/PerspectiveTransform.html) – Calculator

+0

아마 카메라를 설정하지 않았습니다. ..? 완전한 예제없이 작동하지 않는 이유를 알기 힘듭니다. –

답변

3

역순으로 회전했습니다. 아마 당신은 당신이 당신의 코드에 뭔가 다른 것이 있기 때문에 회전을 보지 않을 것입니다. 당신이 정말로 텍스트의 스크롤 "기어"를 원하는 경우

enter image description here

import javafx.application.Application; 
import javafx.scene.PerspectiveCamera; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.control.ScrollPane; 
import javafx.scene.control.ScrollPane.ScrollBarPolicy; 
import javafx.scene.text.Font; 
import javafx.scene.transform.Rotate; 
import javafx.stage.Stage; 

public class StarWarsScrollPane extends Application { 

    private final String text = "It is a period of civil war. Rebel spaceships, " 
      + "striking from a hidden base, have won their first victory against the evil Galactic Empire." 
      + " During the battle, Rebel spies managed to steal secret plans to the Empire's ultimate weapon," 
      + " the DEATH STAR, an armored space station with enough power to destroy an entire planet." 
      + " Pursued by the Empire's sinister agents, Princess Leia races home aboard her starship," 
      + " custodian of the stolen plans that can save her people and restore freedom to the galaxy...."; 

    @Override 
    public void start(Stage primaryStage) { 
     Label label = new Label(text); 
     label.setWrapText(true); 
     label.setFont(Font.font(18)); 
     ScrollPane crawler = new ScrollPane(label); 
     crawler.setVbarPolicy(ScrollBarPolicy.NEVER); 
     crawler.setFitToWidth(true); 

     crawler.getTransforms().add(new Rotate(-50, 300, 200, 20, Rotate.X_AXIS)); 


     Scene scene = new Scene(crawler, 400, 400); 
     scene.setCamera(new PerspectiveCamera()); 


     primaryStage.setScene(scene); 
     primaryStage.show(); 

    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
, 당신은 정말 스크롤 창을 필요로하지 않습니다,하지만 당신은 사용할 수 있습니다

은 나를 위해 작동 텍스트 노드를 만들고 애니메이션으로 변환합니다. 이렇게하는 경우 뒤에 번역 을 추가해야 회전을 추가 할 수 있습니다. 변환은 역순으로 적용됩니다 (마치 아핀 변환 행렬에 오른쪽 곱하기처럼). 여기

이의 예, 여기

import java.util.Random; 

import javafx.animation.KeyFrame; 
import javafx.animation.KeyValue; 
import javafx.animation.Timeline; 
import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.geometry.Rectangle2D; 
import javafx.scene.Cursor; 
import javafx.scene.DepthTest; 
import javafx.scene.PerspectiveCamera; 
import javafx.scene.Scene; 
import javafx.scene.layout.StackPane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Circle; 
import javafx.scene.text.Font; 
import javafx.scene.text.Text; 
import javafx.scene.transform.Rotate; 
import javafx.scene.transform.Translate; 
import javafx.stage.Screen; 
import javafx.stage.Stage; 
import javafx.util.Duration; 

public class StarWarsCrawler extends Application { 

    private final String text = "It is a period of civil war. Rebel spaceships, " 
      + "striking from a hidden base, have won their first victory against the evil Galactic Empire.\n\n" 
      + "During the battle, Rebel spies managed to steal secret plans to the Empire's ultimate weapon," 
      + " the DEATH STAR, an armored space station with enough power to destroy an entire planet.\n\n" 
      + "Pursued by the Empire's sinister agents, Princess Leia races home aboard her starship," 
      + " custodian of the stolen plans that can save her people and restore freedom to the galaxy...."; 

    @Override 
    public void start(Stage primaryStage) { 
     Rectangle2D primaryScreenBounds = Screen.getPrimary().getBounds(); 
     int width = (int) primaryScreenBounds.getWidth() ; 
     int height = (int) primaryScreenBounds.getHeight() ; 

     Text textNode = createText(width); 

     Translate translate = new Translate(); 
     textNode.getTransforms().add(new Rotate(-60, 300, height/2, height/30, Rotate.X_AXIS)); 
     textNode.getTransforms().add(translate); 

     Timeline animation = new Timeline(
       new KeyFrame(Duration.seconds(45), new KeyValue(translate.yProperty(), -10*height)) 
     ); 
     textNode.setTranslateY(2*height); 

     StackPane root = new StackPane(); 

     generateStarField(width, height, root); 

     root.getChildren().add(textNode); 

     Scene scene = createScene(root); 

     primaryStage.setFullScreenExitHint(""); 
     primaryStage.setFullScreen(true); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 

     animation.play(); 
     animation.setOnFinished(e -> Platform.exit()); 
    } 

    private Scene createScene(StackPane root) { 
     Scene scene = new Scene(root, Color.BLACK); 
     PerspectiveCamera camera = new PerspectiveCamera(); 
     camera.setDepthTest(DepthTest.ENABLE); 
     scene.setCamera(camera); 
     scene.setCursor(Cursor.NONE); 
     scene.setOnMouseClicked(e -> { 
      if (e.getClickCount() ==2) { 
       Platform.exit(); 
      } 
     }); 
     return scene; 
    } 

    private Text createText(int width) { 
     Text textNode = new Text(text); 
     textNode.setWrappingWidth(width*1.25); 
     textNode.setFont(Font.font("Franklin Gothic", width/12)); 
     textNode.setFill(Color.rgb(229, 177, 58)); 
     return textNode; 
    } 

    private void generateStarField(int width, int height, StackPane root) { 
     int numStars = width * height/900 ; 

     Random rng = new Random(); 
     for (int i = 1 ; i <= numStars ; i++) { 
      double hue = rng.nextDouble() * 360 ; 
      double saturation = rng.nextDouble() * 0.1 ; 
      Color color = Color.hsb(hue, saturation, 1.0); 
      Circle circle = new Circle(rng.nextInt(width), rng.nextInt(height), 2*rng.nextDouble(), color); 
      circle.setManaged(false); 
      circle.setTranslateZ(rng.nextDouble() * height * 1.25); 
      root.getChildren().add(circle); 
     } 
    } 

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