> For the complete documentation index, see [llms.txt](https://docs.jackf.red/jackfredlib/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.jackf.red/jackfredlib/jackfredlib-colour/gradients.md).

# Gradients

red.jackf.jackfredlib.api.colour.Gradient

`Gradient`s are sequences of [`Colour`](/jackfredlib/jackfredlib-colour/colours.md)s from a range of 0 to 1. They can be sampled at any given point between that range (with it looping in the case of being outside that range).

{% hint style="info" %}
`Colour`s also implement the `Gradient` interface, allowing them to be substituted for any methods taking a gradient.
{% endhint %}

## Blending Modes

JFL: Colour has 3 modes for interpolating between two colours in gradients:

* RGB: Regular linear interpolation for all components
* HSV\_SHORT: Linear intepolation in the HSV space, *taking the shortest path*. This has the effect of keeping the colours bright instead of greying in the middle.
* HSV\_LONG: Linear interpolation in the HSV space, *taking the longest path*.

<figure><img src="https://2232534258-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fz8jNwd4pzhvQ5ZoPB1s3%2Fuploads%2FRg4oxFFYHlWHGA4vSJ5W%2Fblending%20modes.png?alt=media&amp;token=62b160c8-ba12-4398-a44e-9e154bd46a95" alt=""><figcaption><p>Example of blending modes available for a gradient.</p></figcaption></figure>

<figure><img src="https://2232534258-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fz8jNwd4pzhvQ5ZoPB1s3%2Fuploads%2FNwE7AnSqSbqflTw140Zb%2Fcolour%20modes.png?alt=media&amp;token=94491cb4-cfbd-44e5-811e-4d9c4978707b" alt=""><figcaption><p>Overview of what each mode actually does. </p></figcaption></figure>

{% hint style="info" %}
Currently, alpha values are always set to maximum when used in a HSV gradient. This may change in the future.
{% endhint %}

{% hint style="warning" %}
HSV gradients are not stored as such - they're immediately compiled into an equivalent series of RGB gradients which look identical. As such, the HSV points cannot be returned back.
{% endhint %}

## Creating a gradient

### Using `Gradient.of()`&#x20;

For simple gradients, using `Gradient.of()` is likely the easiest method. This generates a gradient with equal intervals between colours and RGB blending.

```java
Gradient SOLAR = Gradient.of(
    Colour.fromRGB(40, 23, 0),
    Colours.YELLOW,
    Colours.ORANGE,
    Colours.WHITE
);
```

<figure><img src="https://2232534258-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fz8jNwd4pzhvQ5ZoPB1s3%2Fuploads%2FrLWjSypA19ltj6gbJq2x%2Fsolar%20gradient.png?alt=media&amp;token=fc0c53cb-209c-4ef2-bba2-db10e9b4253b" alt=""><figcaption><p>The gradient created above</p></figcaption></figure>

### Using `Gradient.linear()`

Using `Gradient.linear()` creates a gradient between two points, using either RGB or HSV blending modes. For examples of these, see [above](#blending-modes).

### Using `Gradient.builder()`

For more control, you can use the given `GradientBuilder` class in order to create one point by point.

{% code fullWidth="true" %}

```java
Gradient complex = Gradient.builder()
    // adding regular colours
    .add(0f, Colours.RED) 
    .add(0.25f, Colours.PINK)
    
    // adding adding another gradient as part of this one
    .addBlock(0.3f, 0.45f, Gradient.linear(Colours.HOT_PINK, Colours.LIME, Gradient.LinearMode.HSV_LONG))
    
    // adding a sharp cut between two colours
    .addCut(0.5f, Colours.GREEN, Colours.BLUE)
    
    // we use Math.nextDown here to get the point 'just before' the NONBINARY gradient starts. This allows us to
    // make a sharp cut manually
    .add(Math.nextDown(0.75f), Colours.AQUAMARINE)
    
    // GradientBuilder.END is the last value before 1f, where it loops. Use it to add an endpoint to your gradient.
    .addBlock(0.75f, GradientBuilder.END, Gradients.NONBINARY)
    .build()
```

{% endcode %}

<figure><img src="https://2232534258-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fz8jNwd4pzhvQ5ZoPB1s3%2Fuploads%2FNXTOxpKzPkycwAvGS95S%2Fadvanced%20gradient.png?alt=media&amp;token=5102c1aa-555c-4e96-8e47-9edc3a345ea4" alt=""><figcaption><p>The gradient created by the above code</p></figcaption></figure>

## Modifying a gradient

It may be useful to modify a gradient after it's been created - you can use it in `GradientBuilder.addBlock`, or some post-processing methods:

### `squish()`

If your gradient has sharp edges, you can `squish` it in order to make transitions smoother. It does this by shrinking it slightly towards the center, then adding points at `0f` and `GradientBuilder.END` with a lerped colour value.

<figure><img src="https://2232534258-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fz8jNwd4pzhvQ5ZoPB1s3%2Fuploads%2FaSWIeYsM6gMZ0YdbWinH%2FnstxFcYwAH.gif?alt=media&amp;token=905e5ddb-fd4f-4452-9145-1baf8f4e1d8e" alt=""><figcaption><p>Example of squishing a gradient - the bottom gradient has been <code>squish</code>ed by 0.1f</p></figcaption></figure>

### `repeat()`

Returns a copy of this gradient shrunken and repeated a certain number of times back to back.

### `reversed()`

Reverses this gradient.

### `slice()`

Returns a subsection of this gradient between the two points. These points can be backwards, and can cross the edges of the gradient boundary. Note that it will not automatically repeat the gradient but will wrap instead.

## Drawing gradients

JFL: Colour contains methods to efficiently draw gradients in a GUI context, horizontally and vertically. These methods are client-only, and can be found under `GradientUtils`. This can draw gradients repeated or backwards depending on what you pass for `gradientStart` and `gradientEnd`.

{% hint style="info" %}
These methods use a single quad for each RGB segment.
{% endhint %}
