Linear gradient's bounds computation takes parent's bounds in account, not the node on which it is applied on

后端 未结 1 371
一向
一向 2021-01-25 19:25

I want to put a linear gradient on a line(width wise ie across it\'s stroke width). This line is a child of a Group node. When I apply linear gradient on line, the color stops a

相关标签:
1条回答
  • 2021-01-25 19:59

    The assumption it takes the group's bounds is not correct. In fact, it's taking the line's bound. And here is the problem.

    If you go to com.sun.prism.j2d.J2DPrismGraphics you'll see that for a shape with a gradient, this is how fill() is done:

    void fill(java.awt.Shape shape) {
        if (paintWasProportional) {
            if (nodeBounds != null) {
                g2d.setPaint(toJ2DPaint(paint, nodeBounds));
            } else {
                g2d.setPaint(toJ2DPaint(paint, shape.getBounds2D()));
            }
        }
        g2d.fill(shape);
    }
    

    The paintWasProportional check gave me a hint to approach your problem with another perspective.

    Let's start by using a LinearGradient object, by code instead of using CSS. Then this will be your starting point:

    @Override
    public void start(Stage primaryStage) throws Exception {
        Group group = new Group();
        primaryStage.setScene(new Scene(group, 200, 350));
    
        Line line = new Line(100, 50, 100, 300);
        LinearGradient linearGradient = new LinearGradient(0d, 0d, 0d, 1d, true,
          CycleMethod.NO_CYCLE, new Stop(0,Color.RED),new Stop(1,Color.GREEN));
    line.setStrokeWidth(36); // 3em
        line.setStroke(linearGradient);
        group.getChildren().add(line);
        primaryStage.show();
    }
    

    With the expected result (the black line is just for reference):

    Gradient 1

    Now, to get the gradient to right, let's change the way we create the gradient, using a non proporcional one:

    LinearGradient linearGradient = new LinearGradient(0d, 50d, 0d, 300d,
           false, CycleMethod.REFLECT,new Stop(0,Color.RED), new Stop(1,Color.GREEN));   
    

    This will have the same result.

    And if you want to change the direction, this is what you need:

    LinearGradient linearGradient = new LinearGradient(100-18d, 0d, 100+18d, 0d,
     false, CycleMethod.REFLECT,new Stop(0,Color.RED), new Stop(1,Color.GREEN));
    

    With this result:

    Gradient 2

    Note you could try now to get this done also by CSS.

    0 讨论(0)
提交回复
热议问题