Skip to content

Commit

Permalink
Masking specs (#54)
Browse files Browse the repository at this point in the history
* Masking specs

Schema and docs for layer masks.

* Additional mask docs

* Single mask sample

* Add hasMask flag

* Review feedback

* Update schema/helpers/mask.json

Co-authored-by: Aidos Sabit <aidosmf@gmail.com>

* Update schema/helpers/mask.json

Co-authored-by: Aidos Sabit <aidosmf@gmail.com>

---------

Co-authored-by: Aidos Sabit <aidosmf@gmail.com>
  • Loading branch information
fmalita and Aidosmf authored Jul 1, 2024
1 parent 48e8e31 commit 82e81ce
Show file tree
Hide file tree
Showing 7 changed files with 1,585 additions and 1 deletion.
23 changes: 23 additions & 0 deletions docs/specs/constants.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,29 @@
</script>
</lottie-playground>

<h2 id="mask-mode">Mask Mode</h2>

{schema_string:constants/mask-mode/description}

{schema_enum:mask-mode}

<lottie-playground example="masks.json">
<title>Example</title>
<form>
<enum title="Mask Mode" value="a">mask-mode</enum>
<input type="range" min="0" max="100" value="100" title="Mask1 Opacity"/>
<input type="range" min="0" max="100" value="100" title="Mask2 Opacity"/>
</form>
<json>lottie.layers[1].masksProperties[1]</json>
<script>
let mask1 = lottie.layers[1].masksProperties[0];
let mask2 = lottie.layers[1].masksProperties[1];
mask1.o.k = Number(data["Mask1 Opacity"]);
mask2.o.k = Number(data["Mask2 Opacity"]);
mask2.mode = data["Mask Mode"];
</script>
</lottie-playground>

<h2 id="stroke-dash-type">Stroke Dash Type</h2>

{schema_string:constants/stroke-dash-type/description}
Expand Down
45 changes: 45 additions & 0 deletions docs/specs/helpers.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,48 @@ The anchor point is highlighted with an orange dot.
{schema_string:helpers/marker/description}

{schema_object:helpers/marker}

<h2 id="mask">Mask</h2>

{schema_string:helpers/mask/description}

{schema_object:helpers/mask}

Masks provide single-channel coverage information (alpha channel) that modulates the layer's
content.

When multiple masks are specified, they are combined (blended) into a single coverage buffer,
in order, based on the [`mode`](constants.md#mask-mode) operator.

Masks are specified in terms of a `Path` plus additional properties. For a given mask path,
the coverage $C_{path}$ is $1$ inside the path, $0$ outside the path, and possibly in the $[0..1]$
range along the path edges (anti-aliasing).

The coverage for a given `Mask` is

$$C = \begin{cases}{lr}
C_{path} \cdot opacity, & \text{when } inv = false \\
C_{path}^{-1} \cdot opacity, & \text{when } inv = true \\
\end{cases}$$

and the cumulative coverage for all masks is

$$C_{cumulative} = \prod_{k=1}^{n} C_k$$

where the product operator is determined by [`mode`](constants.md#mask-mode).
Then the final layer coverage (alpha channel) is

$$C_{layer}\prime = C_{layer} \cdot C_{cumulative}$$

<lottie-playground example="mask.json">
<title>Example</title>
<form>
<input type="range" min="0" max="100" value="100" title="Opacity"/>
</form>
<json>lottie.layers[1].masksProperties[0]</json>
<script>
let mask = lottie.layers[1].masksProperties[0];
mask.o.k = Number(data["Opacity"]);
</script>
</lottie-playground>

Loading

0 comments on commit 82e81ce

Please sign in to comment.