How to rotate the LinearGradient in a given Shape?
Asked Answered
I

2

11

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?

Insecurity answered 19/9, 2014 at 13:7 Comment(3)
Shouldn't new LinearGradient(0, 0, 70, 70...) already do this?Curio
Ok, but what about other values? How to grasp the "rule" of rotating the LinearGradient by any degree?Insecurity
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?Kurtz
C
22

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)).

Curio answered 19/9, 2014 at 13:51 Comment(2)
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).Insecurity
@famfamfam replace the 45 in the code snippet with 90. (Seriously?)Curio
U
2

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

Underarm answered 20/7, 2022 at 10:23 Comment(1)
thank you, may be this is not the right answer to the question, but it's exactly what I was looking for.Aspectual

© 2022 - 2024 — McMap. All rights reserved.