10

I try to find the way to rotate the LinearGradient object nested into e.g. Rectangle object, say:

Rectangle rect = new Rectangle(0, 0, 200, 200);

LinearGradient lg = new LinearGradient(0, 0, 100, 0, false, CycleMethod.REPEAT, new Stop[] {
    new Stop(0, Color.BLACK);
    new Stop(0.5, Color.WHITE);
    new Stop(1, Color.BLACK);
});

rect.setFill(lg);

enter image description here

Now, I try to rotate this lg object, for example for 45 degrees to the left, but without rotating the whole rect. Is there any way to achieve that?

bluevoxel
  • 4,978
  • 11
  • 45
  • 63
  • Shouldn't `new LinearGradient(0, 0, 70, 70...)` already do this? – Marco13 Sep 19 '14 at 13:22
  • Ok, but what about other values? How to grasp the "rule" of rotating the `LinearGradient` by any degree? – bluevoxel Sep 19 '14 at 13:28
  • You give the constructor two points in X-Y coordinates: (x1, y1) and (x2, y2). The angle formed be a line passing through two points with respect to the Y (or X) axis can be calculated easily. It has nothing to do with `LinearGradient`. Can you do this computation? – user1803551 Sep 19 '14 at 13:36

2 Answers2

21

The first parameters that are given to the LinearGradient constructor are the coordinates of the start- and end point of the gradient axis, respectively. This means that you can achieve a "rotated" gradient simply by passing in an appropriately rotated axis.

In the simplest form, for the example that you described, you can use the following pattern:

double angleInRadians = Math.toRadians(45);
double length = 100; 

double endX = Math.cos(angleInRadians) * length;
double endY = Math.sin(angleInRadians) * length;

LinearGradient lg = new LinearGradient(0, 0, endX, endY, ...);

This will result in a gradient rotated by 45 degrees.

The fixed values here will affect the final appearance of the gradient, together with the other parameters. Referring to your example, this gradient with the same "wave length" as before (namely 100), and start with the same color at the upper left corner (i.e. Color.BLACK will be at coordinates (0,0)).

Marco13
  • 53,703
  • 9
  • 80
  • 159
  • 1
    Yes, I got it by drawing it on the piece of paper :) But thank you very much for the explanation. For the `Rectangle` given above the example slopes by given degree can be: 0d `LinearGradient(0,50,100,50)`, 45d `LinearGradient(0,100,100,0)`, 90d `LinearGradient(50,100,50,0)` and 135d `LinearGradient(100,100,0,0)`. – bluevoxel Sep 19 '14 at 13:58
  • @famfamfam replace the `45` in the code snippet with `90`. (Seriously?) – Marco13 Jan 24 '22 at 13:30
1

Trig ratios can be used for a more flexible gradient angle. Please note: It does not implement repeat, hence add more stops in the gradient object.

private fun createGradient(width: Float, height: Float): LinearGradient {
    val mode = TileMode.CLAMP
    val angleInRadians = Math.toRadians(mAngle.toDouble())
    val halfWidth = width / 2
    val halfHeight = height / 2
    val sinAngle = sin(angleInRadians)
    val cosAngle = cos(angleInRadians)
    val x0 = (halfWidth * (1 + sinAngle)).toFloat()
    val y0 = (halfHeight * (1 - cosAngle)).toFloat()
    val x1 = (halfWidth * (1 - sinAngle)).toFloat()
    val y1 = (halfHeight * (1 + cosAngle)).toFloat()

    return LinearGradient(x0, y0, x1, y1, mGradient, null, mode)
}

  • thank you, may be this is not the right answer to the question, but it's exactly what I was looking for. – Rob Mar 22 '23 at 19:06