2015-03-11 2 views
1

Я хотел бы воспроизвести следующий screen с JavaFX и попытался это (зачищенный) код:JafaFX радиальный градиент

public class Main extends Application { 
    @Override 
    public void start(Stage primaryStage) throws Exception{ 
     primaryStage.setTitle("Hello World"); 
     primaryStage.setFullScreen(true); 
     primaryStage.setFullScreenExitHint(""); 

     AnchorPane root = new AnchorPane(); 
     root.setStyle("-fx-background-color: " + 
       "rgb(15,37,74), " + 
       "radial-gradient(center 50% 50%, radius 65%, rgb(97,156,188) 10%, rgb(22,51,93));"); 
     Scene scene = new Scene(root, 600, 400); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

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

Однако у меня есть следующие проблемы, чтобы воспроизвести оригинальную картину:

  • I я не могу генерировать круговой градиент, поскольку AnchorPane является прямоугольником, градиент эллиптический. Насколько я понимаю, documentation круговой градиент невозможен?
  • Градиент исходного изображения не является линейным, но имеет некоторые круги (яркий круг в середине и средний круг снаружи). Я пытался играть и добавлял процент к стоп-цветам, но когда я это делаю (например, rgb(97,156,188) 30%, rgb(22,51,93)), я получаю гораздо более яркую визуализацию эллипса, который я не понимаю. Начало градиента всегда ярче, как это должно быть, и я не знаю, почему:

Pic of ellipse

Может кто-нибудь объяснить мне, что происходит здесь?

ответ

3

Загрузка изображения (800x600 пикселей) с экрана, который вы хотите дублировать, и с помощью набора цветов я получаю следующие значения (десятичные значения r, g, b), проходящие от центра (400, 300) к левому краю (0, 300):

  • (400, 300): (104, 163, 193)
  • (300, 300): (87, 145, 182)
  • (200, 300): (60, 113, 163)
  • (100, 300): (38, 85, 137)
  • (0, 300): (23, 56, 99)

Это выглядит достаточно близко к линейному мне (там, возможно, некоторые общие нечеткость и JPEG сжатие изменить значения немного).

Так что это, кажется, хорошее приближение:

root.setStyle("-fx-background-color: radial-gradient(center 50% 50%, radius 50%, rgb(104, 163, 193) 0%, rgb(23, 56, 99) 100%);"); 

Я не вижу способ сделать это круговое используя проценты: вы должны использовать фактическую длину. Если размер может измениться, тогда, конечно, вам нужно ответить на это; вы можете сделать это со связыванием следующим образом:

root.styleProperty().bind(Bindings.createStringBinding(() -> 
     String.format("-fx-background-color: radial-gradient(center %dpx %dpx, radius %dpx, rgb(104, 163, 193) 0%%, rgb(23, 56, 99) 100%%);", 
       (int) (root.getWidth()/2), (int) (root.getHeight()/2), (int)(Math.max(root.getWidth(), root.getHeight())/2)), 
       root.widthProperty(), root.heightProperty())); 

Помните, что это не очень эффективный способ сделать это; встроенные стили, как правило, являются самым медленным способом применения CSS к узлу, и здесь вы меняете встроенный стиль при каждом небольшом изменении размера узла. Однако, похоже, он работает очень хорошо в моей системе; просто имейте в виду, что это не может быть хорошим способом применить градиент ко многим узлам в одном представлении.

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