Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaFX create transparent radial gradient

Tags:

I want to create a circle simulating a light, and I need a radial gradient. I want it to be yellow in the center and transparent in the outer side.

I tried this but I'm not getting the expected result.

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

like image 799
AwesomeGuy Avatar asked Jan 08 '20 14:01

AwesomeGuy


1 Answers

I haven't worked with RadialGradient before so I was curious and honestly when first reading the documentation without looking at your code I did the exact same as you which resulted in this: enter image description here

I read the documentation for RadialGradient and after reading about the stop#offset which says:

The application provides an array of Stops specifying how to distribute the colors along the gradient. The Stop#offset variable must be the range 0.0 to 1.0 and act like keyframes along the gradient. They mark where the gradient should be exactly a particular color.

I figured that, if I'd put stops at 0 and 1, then the yellow color would be 50% transparent halfway out. This did not look to be the case, at least if I have a white background. If the background is white then I can't even see that the yellow circle is transparent on the outer edge (changing the background color to, for example, green made it more visible but it was still not the result that I was expecting but perhaps it's just me thinking that it would be more transparent).

Anyhow, after playing around with it for a bit I ended up with this:

enter image description here

All I had to do to get this was to change the second stop from 1 to 0.5. I'm not sure if it's good enough but from what you wrote it could be:

I want to create a circle simulating a light, and I need a radial gradient. I want it to be yellow in the center and transparent in the outer side.

Also, it's possible to style nodes to have gradient backgrounds through CSS so as an alternate solution (inspired by the answer from james_D here) I styled a region as well which ended up like this: enter image description here

Below is the code from which I created these three different images (even though the CSS solution might not be what you want I still included it). Note that I just used inline-styles for the sake of creating a quick example.

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

Perhaps an unnecessarily long answer to say that you might only have to change a single value.

like image 159
Robert Avatar answered Oct 21 '22 07:10

Robert