2017-01-16 15 views
1

У меня возникла проблема с вращением usercontrol в javafx. Моя настройка такова:Поверните прокрутку по оси X в javafx - звездные войны, подобные эффекту

У меня есть сцена в центре прокрутки с разрешением 400 на 600, которая называется scrollpane, а затем динамически заполняется vbox, содержащим список меток с текстом.

Что я хочу сделать, это добавить поворот на этой панели, чтобы он выглядел как текст введения starwars. Мне удалось получить анимацию, которая прокручивается через текст, но при попытке повернуть панель над 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)); 

Как вы можете видеть текст направлен на нужный угол, а сам контроль не является на самом деле 3d повернуты по оси Х. Что мне нужно добавить, чтобы перейти от того, что у меня есть к желаемому результату? (То, что верх панели в абсолютных пикселях менее широк по сравнению с нижней).

+0

Здесь нужно два свойства, курсивный формат и масштаб, тем ближе текст к верхней части вашего 'ScrollPane' тем меньше он получает, и чем ближе он попадает в нижнюю часть, чем больше он получает. –

+1

Возможно применение эффекта преобразования перспективы будет работать: [PerspectiveTransform] (https://docs.oracle.com/javafx/2/api/javafx/scene/effect/PerspectiveTransform.html) – Calculator

+0

Возможно, вы не установили камеру. ..? Трудно понять, почему он не работает без полного примера. –

ответ

3

Вы повернули его назад; вероятно, вы не видите поворот, потому что у вас что-то еще не так в коде.

Это работает для меня:

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

enter image description here

Обратите внимание, что если вы действительно хотите прокрутки «ползти» текста, вы на самом деле не нужна панель прокрутки, но вы можете просто использовать текстовый узел и перевести его в анимацию. Если вы это сделаете, обязательно добавьте перевод после: вы добавляете поворот: преобразования применяются в обратном порядке (как если бы вы правильно умножали матрицы аффинного преобразования).

Вот пример этого;)

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

 Смежные вопросы

  • Нет связанных вопросов^_^