Skip to content

Commit

Permalink
Add Gradient Fill + Stroke (lottie#51)
Browse files Browse the repository at this point in the history
* Add gradient fill and stroke to schema and docs

* Minor changes to gradient wording/formatting

* Ignore base gradient when validating docs links

* Polish gradient docs

Enhance gradient description
Use stop terminology
Add more playground examples
  • Loading branch information
b-wils authored Jul 2, 2024
1 parent 82e81ce commit fd09622
Show file tree
Hide file tree
Showing 17 changed files with 3,237 additions and 0 deletions.
18 changes: 18 additions & 0 deletions docs/specs/constants.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,21 @@
{schema_string:constants/stroke-dash-type/description}

{schema_enum:stroke-dash-type}

<h2 id="gradient-type">Gradient Type</h2>

{schema_string:constants/gradient-type/description}

{schema_enum:gradient-type}

<lottie-playground example="gradient.json">
<title>Example</title>
<form>
<enum title="Type" value="1">gradient-type</enum>
</form>
<json>lottie.layers[1].shapes[0].it[1]</json>
<script>
var gradient = lottie.layers[1].shapes[0].it[1];
gradient.t = Number(data["Type"]);
</script>
</lottie-playground>
14 changes: 14 additions & 0 deletions docs/specs/properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,17 @@ Animatable {link:values/color}.
{schema_string:properties/color-keyframe/description}

{schema_object:properties/color-keyframe}

<h3 id="gradient-property">Gradient</h3>

Animatable {link:values/gradient}.

{schema_object:properties/gradient-property}

Color count is not animatable.

<h4 id="gradient-keyframe">Gradient Keyframe</h4>

{schema_string:properties/gradient-keyframe/description}

{schema_object:properties/gradient-keyframe}
81 changes: 81 additions & 0 deletions docs/specs/shapes.md
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,87 @@ $$
</script>
</lottie-playground>

<h3 id="gradient-fill"><span id="gradient-fill">Gradient Fill</span></h3>

{schema_string:shapes/gradient-fill/description}

{schema_object:shapes/gradient-fill}

<lottie-playground example="gradient.json">
<title>Example</title>
<form>
<input title="Start X" type="range" min="0" max="512" value="256"/>
<input title="Start Y" type="range" min="0" max="512" value="496"/>
<input title="End X" type="range" min="0" max="512" value="256"/>
<input title="End Y" type="range" min="0" max="512" value="16"/>
<enum title="Type" value="1">gradient-type</enum>
<input title="Highlight" type="range" min="0" max="100" value="0"/>
<input title="Highlight Angle" type="range" min="0" max="360" value="0"/>
</form>
<json>lottie.layers[1].shapes[0].it[1]</json>
<script>
var gradient = lottie.layers[1].shapes[0].it[1];
var start_marker = lottie.layers[0].shapes[1].it[1];
var end_marker = lottie.layers[0].shapes[0].it[1];
gradient.s.k = start_marker.p.k = [data["Start X"], data["Start Y"]];
gradient.e.k = end_marker.p.k = [data["End X"], data["End Y"]];
gradient.t = Number(data["Type"]);
if (gradient.t === 2) {
gradient.h = {
a: 0,
k: data["Highlight"]
};
gradient.a = {
a: 0,
k: data["Highlight Angle"]
};
} else {
delete gradient.h;
delete gradient.a;
}
</script>
</lottie-playground>

<h3 id="gradient-stroke"><span id="gradient-stroke">Gradient Stroke</span></h3>

{schema_string:shapes/gradient-stroke/description}

{schema_object:shapes/gradient-stroke}

<lottie-playground example="gradient-stroke.json">
<title>Example</title>
<form>
<input title="Start X" type="range" min="0" max="512" value="256"/>
<input title="Start Y" type="range" min="0" max="512" value="496"/>
<input title="End X" type="range" min="0" max="512" value="256"/>
<input title="End Y" type="range" min="0" max="512" value="16"/>
<enum title="Type" value="1">gradient-type</enum>
<input title="Highlight" type="range" min="0" max="100" value="0"/>
<input title="Highlight Angle" type="range" min="0" max="360" value="0"/>
</form>
<json>lottie.layers[1].shapes[1]</json>
<script>
var gradient = lottie.layers[1].shapes[1];
var start_marker = lottie.layers[0].shapes[1].it[1];
var end_marker = lottie.layers[0].shapes[0].it[1];
gradient.s.k = start_marker.p.k = [data["Start X"], data["Start Y"]];
gradient.e.k = end_marker.p.k = [data["End X"], data["End Y"]];
gradient.t = Number(data["Type"]);
if (gradient.t === 2) {
gradient.h = {
a: 0,
k: data["Highlight"]
};
gradient.a = {
a: 0,
k: data["Highlight Angle"]
};
} else {
delete gradient.h;
delete gradient.a;
}
</script>
</lottie-playground>

<h2 id="modifier">Modifiers</h2>

Expand Down
63 changes: 63 additions & 0 deletions docs/specs/values.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,69 @@ RGB component.

* {lottie_hexcolor: #FF8000}

<h2 id="gradient">Gradient</h2>

The gradient appearance is specified in terms of color stops and opacity stops.
Color stops are defined as `(position, color)` tuples, where the position is a normalized `[0..1]`value along the gradient axis `[startpoint -> endpoint]`, and the color is 3 floats representing the RGB components. Transparency (opacity) stops are defined as `(position, color)` tuples, where position is similar to color stops' position.

All color and opacity stops are stored sequentially by ascending offsets in a flattened float array (color stops followed by opacity stops), with 4 floats per color stop and 2 floats per opacity stops. Thus, given color stops and opacity stops, the expected size for the gradient data array is `4 * Nc + 2 * No`.

The color stop count is typically specified in a separate field from the gradient values, while the count of opacity stops can be inferred from the data array length: `No = (length - 4 * Nc)/2`.

<h3>Gradient without transparency</h3>

So let's say you want these colors:

* {lottie_color:0.16, 0.18, 0.46}
* {lottie_color:0.2, 0.31, 0.69}
* {lottie_color:0.77, 0.85, 0.96}

the array will look like the following:

`[0, 0.16, 0.18, 0.46, 0.5, 0.2, 0.31, 0.69, 1, 0.77, 0.85, 0.96]`

| Value | Description |
|-----------|---|
| `0` | Offset of the 1st color (`0` means at the start) |
| `0.16` | Red component for the 1st color |
| `0.18` | Green component for the 1st color |
| `0.46` | Blue component for the 1st color |
| `0.5` | Offset of the 2nd color (`0.5` means half way) |
| `0.2` | Red component for the 2nd color |
| `0.31` | Green component for the 2nd color |
| `0.69` | Blue component for the 2nd color |
| `1` | Offset of the 3rd color (`1` means at the end) |
| `0.77` | Red component for the 3rd color |
| `0.85` | Green component for the 3rd color |
| `0.96` | Blue component for the 3rd color |

<h3>Gradient with transparency</h3>

Transparency stops are added at the end. Transparency stops may or may
not match the count and offset of color stops.

So assume the same colors as before, but opacity of 80% for the first color and 100% for the other two.

The array will look like this:

`[0, 0.16, 0.18, 0.46, 0.5, 0.2, 0.31, 0.69, 1, 0.77, 0.85, 0.96, 0, 0.8, 0.5, 1, 1, 1]`

It's the same array as the case without transparency but with the following values added at the end:


| Value | Description |
|-----------|---|
| `0` | Offset of the 1st color (`0` means at the start) |
| `0.8` | Alpha component for the 1st color |
| `0.5` | Offset of the 2nd color (`0.5` means half way) |
| `1` | Alpha component for the 2nd color |
| `1` | Offset of the 3rd color (`1` means at the end) |
| `1` | Alpha component for the 3rd color |

<h3>Gradient Example</h3>

{editor_example:gradient}

<h2 id="bezier">Bezier Shape</h2>

{schema_string:values/bezier/description}
Expand Down
Loading

0 comments on commit fd09622

Please sign in to comment.