JavaFX создает прозрачный радиальный градиент - PullRequest
5 голосов
/ 08 января 2020

Я хочу создать круг, имитирующий свет, и мне нужен радиальный градиент. Я хочу, чтобы он был желтым в центре и прозрачным на внешней стороне.

Я пробовал это, но не получил ожидаемый результат.

RadialGradient gradient1 = new RadialGradient(0, 0, 0.5, 0.5, 1, true, CycleMethod.NO_CYCLE, new Stop[] {
            new Stop(0, Color.YELLOW),
            new Stop(1, Color.TRANSPARENT)
});

ansp

1 Ответ

4 голосов
/ 09 января 2020

Раньше я не работал с RadialGradient, поэтому мне было любопытно и честно, когда, впервые прочитав документацию, не глядя на ваш код, я сделал то же самое, что и вы, что привело к следующему: enter image description here

Я прочитал документацию для RadialGradient и после прочтения о stop # offset , в котором говорится:

Приложение предоставляет массив Останавливает указание, как распределить цвета вдоль градиента. Переменная Stop # offset должна иметь диапазон от 0,0 до 1,0 и действовать как ключевые кадры вдоль градиента. Они отмечают, где градиент должен быть точно определенного цвета.

Я подумал, что, если бы я поставил стопы на 0 и 1, тогда желтый цвет был бы на 50% прозрачным на полпути. Это не похоже на случай, по крайней мере, если у меня белый фон. Если фон белый, то я даже не вижу, чтобы желтый круг был прозрачным по внешнему краю (изменение цвета фона, например, на зеленый сделало его более заметным, но это был не тот результат, которого я ожидал, но, возможно, это просто я думаю, что это будет более прозрачным).

Во всяком случае, немного поиграв с этим, я в итоге получил следующее:

enter image description here

Все, что мне нужно было сделать, это изменить второй стоп с 1 на 0,5. Я не уверен, что это достаточно хорошо, но из того, что вы написали, это может быть:

Я хочу создать круг, имитирующий свет, и мне нужен радиальный градиент. Я хочу, чтобы он был желтым в центре и прозрачным на внешней стороне.

Кроме того, можно стилизовать узлы, чтобы иметь градиентный фон с помощью CSS, так как альтернативное решение (вдохновлено ответом от james_D здесь ) Я также разработал область, которая в итоге выглядит следующим образом: enter image description here

Ниже приведен код, из которого я создал эти три разных изображения ( хотя решение CSS может быть не тем, что вы хотите, я все же включил его). Обратите внимание, что я просто использовал встроенные стили для создания быстрого примера.

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

@Override
public void start(Stage aStage) throws Exception {
    Label label = new Label("RadialGradient: stops at 0 and 1");
    RadialGradient yours = new RadialGradient(0, 0, 0.5, 0.5, 1, true, CycleMethod.NO_CYCLE, new Stop[] {
            new Stop(0, Color.YELLOW),
            new Stop(1, Color.TRANSPARENT)
    });
    Circle yourCircle = new Circle(100, yours);

    // Changed the stops from 0 and 1 to now go between 0 and 0.5, thats all really. I played around with some more stops but I 
    // didn't really get any results that I was happy with. 
    Label label2 = new Label("RadialGradient: stops at 0 and 0.5");
    RadialGradient gradient = new RadialGradient(0, 0, 0.5, 0.5, 1, true, CycleMethod.NO_CYCLE, new Stop[] {
            new Stop(0, Color.YELLOW),
            new Stop(0.5, Color.TRANSPARENT)
    });
    Circle circle = new Circle(100, gradient);

    // Another way of getting the desired gradient effect can be achieved with CSS. 
    Label label3 = new Label("Alternate way, Region + CSS");
    Region region = new Region();
    region.setStyle(""
            + "-fx-background-color: radial-gradient(center 50% 50%, radius 50%, rgb(251, 255, 0) 0%, rgb(243, 241, 94) 25%,rgba(245, 228, 0, 0) 100%);"
            + "-fx-background-radius:50;");
    region.setPrefWidth(200);
    region.setPrefHeight(200);

    final VBox root = new VBox();
    //  root.setStyle("-fx-background-color:green"); // I just used this so that I could "see" how transparent the circles actually were.
    root.getChildren().addAll(label, yourCircle, label2, circle, label3, region);
    final Scene scene = new Scene(root, 200, 640);
    aStage.setScene(scene);
    aStage.show();
}

Возможно, излишне длинный ответ, чтобы сказать, что может изменить только одно значение.

...