Skip to content

Commit 282629a

Browse files
authored
🎭 Masks (#221)
1 parent 3e78e0d commit 282629a

File tree

25 files changed

+254
-59
lines changed

25 files changed

+254
-59
lines changed

docs/docs/assets/mask/alpha.png

18.1 KB
Loading
19.7 KB
Loading

docs/docs/backdrop-filters.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ const Filter = () => {
3737
height={256}
3838
fit="cover"
3939
/>
40-
<BackdropFilter clip={{ x: 0, y: 128, width: 256, height: 128 }}>
41-
<ColorMatrix matrix={BLACK_AND_WHITE} />
42-
</BackdropFilter>
40+
<BackdropFilter
41+
clip={{ x: 0, y: 128, width: 256, height: 128 }}
42+
filter={<ColorMatrix matrix={BLACK_AND_WHITE} />}
43+
/>
4344
</Canvas>
4445
);
4546
};

docs/docs/image.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Images can be draw by specifying the output rectangle and how the image should f
99

1010
| Name | Type | Description |
1111
| :----- | :-------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------ |
12-
| image | `IImage` | Image instance. |
12+
| image | `SkImage` | Image instance. |
1313
| x | `number` | Left position of the destination image. |
1414
| y | `number` | Right position of the destination image. |
1515
| width | `number` | Width of the destination image. |

docs/docs/mask.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
id: mask
3+
title: Mask
4+
sidebar_label: Mask
5+
slug: /mask
6+
---
7+
8+
The `Mask` component hides an element by masking the content at specific points.
9+
Just like its [CSS counterpart](https://developer.mozilla.org/en-US/docs/Web/CSS/mask), there are two modes available:
10+
* `alpha`: This mode indicates that the transparency (alpha channel) values of the mask layer image should be used as the mask values. This is how masks work in Figma.
11+
* `luminance`: This mode indicates that the luminance values of the mask layer image should be used as the mask values. This is how masks work in SVG.
12+
13+
The first child of `Mask` is the drawing to be used as a mask, and the remaining children are the drawings to mask.
14+
15+
By default, the mask is not clipped. If you want to clip the mask with the bounds of the content it is masking, use the `bounds` property.
16+
17+
| Name | Type | Description |
18+
|:----------|:--------------------------|:--------------------------------------------------------------|
19+
| mode? | `alpha` or `luminance` | Is it a luminance or alpha mask (default is `alpha`) |
20+
| bounds? | `SkRect` | Optional rectangle to clip the mask with |
21+
| mask | `ReactNode[] | ReactNode` | Mask definition |
22+
| children | `ReactNode[] | ReactNode` | Content to mask |
23+
24+
## Alpha Mask
25+
26+
Opaque pixels will be visible and transparent pixels invisible.
27+
28+
```tsx twoslash
29+
import {Canvas, Mask, Group, Circle, Rect} from "@shopify/react-native-skia";
30+
31+
const Demo = () => (
32+
<Canvas style={{ width: 256, height: 256 }}>
33+
<Mask
34+
mask={
35+
<Group>
36+
<Circle cx={128} cy={128} r={128} opacity={0.5} />
37+
<Circle cx={128} cy={128} r={64} />
38+
</Group>
39+
}
40+
>
41+
<Rect x={0} y={0} width={256} height={256} color="lightblue" />
42+
</Mask>
43+
</Canvas>
44+
);
45+
```
46+
47+
### Result
48+
49+
![Alpha Mask](assets/mask/alpha.png)
50+
51+
## Luminance Mask
52+
53+
White pixels will be visible and black pixels invisible.
54+
55+
```tsx twoslash
56+
import {Canvas, Mask, Group, Circle, Rect} from "@shopify/react-native-skia";
57+
58+
const Demo = () => (
59+
<Canvas style={{ width: 256, height: 256 }}>
60+
<Mask
61+
mode="luminance"
62+
mask={
63+
<Group>
64+
<Circle cx={128} cy={128} r={128} color="white" />
65+
<Circle cx={128} cy={128} r={64} color="black" />
66+
</Group>
67+
}
68+
>
69+
<Rect x={0} y={0} width={256} height={256} color="lightblue" />
70+
</Mask>
71+
</Canvas>
72+
);
73+
```
74+
75+
### Result
76+
77+
![Luminance Mask](assets/mask/luminance.png)

docs/docs/path-effects.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ Stamp the specified path to fill the shape, using the matrix to define the latic
159159
| Name | Type | Description |
160160
|:----------|:-------------|:------------------------------|
161161
| path | `PathDef` | The path to use |
162-
| matrix | `IMatrix` | Matrix to be applied |
162+
| matrix | `SkMatrix` | Matrix to be applied |
163163
| children? | `PathEffect` | Optional path effect to apply |
164164

165165
### Example

docs/docs/shaders/images.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ It will use cubic sampling.
1212

1313
| Name | Type | Description |
1414
|:-----------|:---------------|:-----------------------------------|
15-
| image | `IImage` | Image instance. |
15+
| image | `SkImage` | Image instance. |
1616
| tx? | `TileMode` | Can be `clamp`, `repeat`, `mirror`, or `decal`. |
1717
| ty? | `TileMode` | Can be `clamp`, `repeat`, `mirror`, or `decal`. |
1818
| fm? | `FilterMode`. | Can be `linear` or `nearest`. |
1919
| mm? | `MipmapMode` | Can be `none`, `linear` or `nearest`. |
2020
| fit? | `Fit`. | Calculate the transformation matrix to fit the rectangle defined by `fitRect`. See [images](images). |
21-
| rect? | `IRect` | The destination reactangle to calculate the transformation matrix via the `fit` property. |
21+
| rect? | SkRect` | The destination reactangle to calculate the transformation matrix via the `fit` property. |
2222
| transform? | `Transforms2d` | see [transformations](/docs/group#transformations). |
2323

2424
### Example

docs/sidebars.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ const sidebars = {
3737
label: "Group",
3838
id: "group",
3939
},
40+
{
41+
type: "doc",
42+
label: "Mask",
43+
id: "mask",
44+
},
4045
{
4146
collapsed: true,
4247
type: "category",

example/src/Examples/API/BlendModes.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
/* eslint-disable max-len */
22
import React from "react";
3-
import { Canvas, Circle, Group, Path, Skia } from "@shopify/react-native-skia";
3+
import {
4+
Canvas,
5+
Circle,
6+
Group,
7+
Path,
8+
Skia,
9+
Text,
10+
} from "@shopify/react-native-skia";
411
import { Dimensions } from "react-native";
512

613
const { width } = Dimensions.get("window");
@@ -72,8 +79,17 @@ export const BlendModes = () => {
7279
]}
7380
key={blendMode}
7481
>
75-
<Path path={src} color="lightblue" blendMode={blendMode} />
76-
<Path path={dst} color="pink" blendMode={blendMode} />
82+
<Group blendMode={blendMode}>
83+
<Path path={src} color="lightblue" />
84+
<Path path={dst} color="pink" />
85+
</Group>
86+
<Text
87+
text={blendMode}
88+
x={0}
89+
y={0}
90+
familyName="source-sans-pro-semi-bold"
91+
size={50}
92+
/>
7793
</Group>
7894
))}
7995
</Group>

example/src/Examples/API/Clipping2.tsx

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,17 @@ import React from "react";
22
import { StyleSheet, Dimensions, ScrollView } from "react-native";
33
import {
44
Skia,
5-
PaintStyle,
65
Canvas,
76
Image,
87
Group,
8+
Circle,
9+
Rect,
10+
Mask,
911
useImage,
1012
} from "@shopify/react-native-skia";
1113

1214
const { width } = Dimensions.get("window");
1315
const SIZE = width / 4;
14-
const paint = Skia.Paint();
15-
paint.setAntiAlias(true);
16-
paint.setColor(Skia.Color("#61DAFB"));
17-
18-
const strokePaint = paint.copy();
19-
strokePaint.setStyle(PaintStyle.Stroke);
20-
strokePaint.setStrokeWidth(2);
2116

2217
const star = Skia.Path.MakeFromSVGString(
2318
// eslint-disable-next-line max-len
@@ -72,6 +67,30 @@ export const Clipping = () => {
7267
/>
7368
</Group>
7469
</Canvas>
70+
<Canvas style={{ width, height: 200 }}>
71+
<Mask
72+
mode="alpha"
73+
mask={
74+
<Group>
75+
<Circle cx={100} cy={100} r={100} color="#00000066" />
76+
<Circle cx={100} cy={100} r={50} color="black" />
77+
</Group>
78+
}
79+
>
80+
<Rect x={0} y={0} width={256} height={256} color="lightblue" />
81+
</Mask>
82+
<Mask
83+
mode="luminance"
84+
mask={
85+
<Group>
86+
<Circle cx={300} cy={100} r={100} color="white" />
87+
<Circle cx={300} cy={100} r={50} color="black" />
88+
</Group>
89+
}
90+
>
91+
<Rect x={200} y={0} width={200} height={200} color="lightblue" />
92+
</Mask>
93+
</Canvas>
7594
</ScrollView>
7695
);
7796
};

0 commit comments

Comments
 (0)