Skip to content

Commit

Permalink
Implement new color and image filters for RN Web (#840)
Browse files Browse the repository at this point in the history
  • Loading branch information
wcandillon authored Aug 24, 2022
1 parent d144625 commit 380a110
Show file tree
Hide file tree
Showing 34 changed files with 301 additions and 138 deletions.
Binary file removed docs/docs/assets/mask/alpha.png
Binary file not shown.
Binary file removed docs/docs/assets/mask/luminance.png
Binary file not shown.
11 changes: 0 additions & 11 deletions docs/docs/getting-started/web.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -166,17 +166,6 @@ LoadSkiaWeb({
Below are the React Native Skia APIs which are not yet supported on React Native Web.
Some of these features are a work in progress, and some others will come later.

**Work in Progress**

* `ColorFilter::MakeLuma`
* `ImageFilter::MakeBlend`
* `ImageFilter::MakeDilate`
* `ImageFilter::MakeErode`
* `ImageFilter::MakeDropShadowOnly`
* `ImageFilter::MakeDropShadow`
* `ImageFilter::MakeDisplacementMap`
* `ImageFilter::MakeOffset`

**Coming soon**

* `Font::GetPath`
Expand Down
Binary file removed docs/docs/image-filters/assets/drop-shadow.png
Binary file not shown.
Binary file removed docs/docs/image-filters/assets/inner-shadow.png
Binary file not shown.
Binary file removed docs/docs/image-filters/assets/morphology.png
Binary file not shown.
Binary file removed docs/docs/image-filters/assets/offset.png
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/docs/image-filters/morphology.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ export const MorphologyDemo = () => {
};
```

![Morphology Image Filter](./assets/morphology.png)
<img src={require("/static/img/image-filters/morphology.png").default} width="256" height="256" />
2 changes: 1 addition & 1 deletion docs/docs/image-filters/offset.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ const Filter = () => {
};
```

![Offset](./assets/offset.png)
<img src={require("/static/img/image-filters/offset.png").default} width="256" height="256" />
4 changes: 2 additions & 2 deletions docs/docs/image-filters/shadows.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const Neumorphism = () => {

### Result

![Drop Shadow](assets/drop-shadow.png)
<img src={require("/static/img/image-filters/dropshadow.png").default} width="256" height="256" />

## Inner Shadow

Expand All @@ -83,4 +83,4 @@ const Neumorphism = () => {

### Result

![Inner Shadow](assets/inner-shadow.png)
<img src={require("/static/img/image-filters/innershadow.png").default} width="256" height="256" />
4 changes: 2 additions & 2 deletions docs/docs/mask.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const Demo = () => (

### Result

![Alpha Mask](assets/mask/alpha.png)
<img src={require("/static/img/mask/alpha-mask.png").default} width="256" height="256" />

## Luminance Mask

Expand Down Expand Up @@ -74,4 +74,4 @@ const Demo = () => (

### Result

![Luminance Mask](assets/mask/luminance.png)
<img src={require("/static/img/mask/luminance-mask.png").default} width="256" height="256" />
Binary file added docs/static/img/image-filters/dropshadow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/image-filters/innershadow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/image-filters/morphology.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/image-filters/offset.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/mask/alpha-mask.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/mask/luminance-mask.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package/cpp/api/JsiSkPathFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class JsiSkPathFactory : public JsiSkHostObject {
JSI_EXPORT_FUNC(JsiSkPathFactory, MakeFromCmds),
JSI_EXPORT_FUNC(JsiSkPathFactory, MakeFromText))

JsiSkPathFactory(std::shared_ptr<RNSkPlatformContext> context)
JsiSkPathFactory(std::shared_ptr<RNSkPlatformContext> context)
: JsiSkHostObject(std::move(context)) {}
};

Expand Down
2 changes: 1 addition & 1 deletion package/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"typescript": "^4.6.4"
},
"dependencies": {
"canvaskit-wasm": "^0.35.0",
"canvaskit-wasm": "^0.36.0",
"react-reconciler": "^0.26.2"
},
"eslintIgnore": [
Expand Down
2 changes: 1 addition & 1 deletion package/src/renderer/__tests__/ColorFilters.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ describe("Color Filters", () => {
</Group>
</>
);
processResult(surface, docPath("color-filters/color-blend.png"), true);
processResult(surface, docPath("color-filters/color-blend.png"));
});
});
2 changes: 1 addition & 1 deletion package/src/renderer/__tests__/CoonPatch.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ describe("CoonsPatch", () => {
patch={[topLeft, topRight, bottomRight, bottomLeft]}
/>
);
processResult(surface, "snapshots/coons-patch/simple.png", true);
processResult(surface, "snapshots/coons-patch/simple.png");
});
});
98 changes: 98 additions & 0 deletions package/src/renderer/__tests__/ImageFilters.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import React from "react";

import { docPath, processResult } from "../../__tests__/setup";
import {
Fill,
Image,
Morphology,
Offset,
RoundedRect,
Shadow,
Text,
} from "../components";

import {
drawOnNode,
loadFont,
fontSize,
loadImage,
width,
height,
} from "./setup";

describe("Test Image Filters", () => {
it("Should change the text morphology", () => {
const font = loadFont("skia/__tests__/assets/Roboto-Medium.ttf", fontSize);
const surface = drawOnNode(
<>
<Fill color="white" />
<Text text="Hello World" x={96} y={96} font={font} />
<Text text="Hello World" x={96} y={192} font={font}>
<Morphology radius={3} />
</Text>
<Text text="Hello World" x={96} y={288} font={font}>
<Morphology radius={1} operator="erode" />
</Text>
</>
);
processResult(surface, docPath("image-filters/morphology.png"));
});
it("Should offset the image", () => {
const image = loadImage("skia/__tests__/assets/oslo.jpg");
const surface = drawOnNode(
<>
<Fill color="lightblue" />
<Image
image={image}
x={0}
y={0}
width={width}
height={height}
fit="cover"
>
<Offset x={192} y={192} />
</Image>
</>
);
processResult(surface, docPath("image-filters/offset.png"));
});
it("Should draw a dropshadow", () => {
const surface = drawOnNode(
<>
<Fill color="lightblue" />
<RoundedRect
x={96}
y={96}
width={576}
height={576}
r={96}
color="lightblue"
>
<Shadow dx={36} dy={36} blur={75} color="#93b8c4" />
<Shadow dx={-36} dy={-36} blur={75} color="#c7f8ff" />
</RoundedRect>
</>
);
processResult(surface, docPath("image-filters/dropshadow.png"));
});

it("Should draw a innershadow", () => {
const surface = drawOnNode(
<>
<Fill color="lightblue" />
<RoundedRect
x={96}
y={96}
width={576}
height={576}
r={96}
color="lightblue"
>
<Shadow dx={36} dy={36} blur={75} color="#93b8c4" inner />
<Shadow dx={-36} dy={-36} blur={75} color="#c7f8ff" inner />
</RoundedRect>
</>
);
processResult(surface, docPath("image-filters/innershadow.png"));
});
});
2 changes: 1 addition & 1 deletion package/src/renderer/__tests__/Text.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,6 @@ describe("Test different text examples", () => {
<Text text="🙋🌎" font={emojiFont} y={fontSize} x={0} />
</>
);
processResult(surface, docPath("text/text-emoji.png"), true);
processResult(surface, docPath("text/text-emoji.png"));
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const BLACK_AND_WHITE = [

describe("Backdrop Filters", () => {
it("A black and white color filter as backdrop color filter", () => {
const image = loadImage("skia/__tests__/assets/oslo.jpg")!;
const image = loadImage("skia/__tests__/assets/oslo.jpg");
expect(image).toBeTruthy();
const surface = drawOnNode(
<Group>
Expand All @@ -40,7 +40,7 @@ describe("Backdrop Filters", () => {
processResult(surface, docPath("black-and-white-backdrop-filter.png"));
});
it("Blur backdrop filter", () => {
const image = loadImage("skia/__tests__/assets/oslo.jpg")!;
const image = loadImage("skia/__tests__/assets/oslo.jpg");
expect(image).toBeTruthy();
const surface = drawOnNode(
<Group>
Expand Down
45 changes: 45 additions & 0 deletions package/src/renderer/__tests__/documentation/Mask.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from "react";

import { docPath, processResult } from "../../../__tests__/setup";
import { Group, Mask, Circle, Rect } from "../../components";
import { drawOnNode, width } from "../setup";

describe("Mask Documentation Examples", () => {
it("Should draw an alpha mask", () => {
const r = width / 2;
const surface = drawOnNode(
<>
<Mask
mask={
<Group>
<Circle cx={r} cy={r} r={r} opacity={0.5} />
<Circle cx={r} cy={r} r={r / 2} />
</Group>
}
>
<Rect x={0} y={0} width={r * 2} height={r * 2} color="lightblue" />
</Mask>
</>
);
processResult(surface, docPath("mask/alpha-mask.png"));
});
it("Should draw an luminance mask", () => {
const r = width / 2;
const surface = drawOnNode(
<>
<Mask
mode="luminance"
mask={
<Group>
<Circle cx={r} cy={r} r={r} color="white" />
<Circle cx={r} cy={r} r={r / 2} color="black" />
</Group>
}
>
<Rect x={0} y={0} width={r * 2} height={r * 2} color="lightblue" />
</Mask>
</>
);
processResult(surface, docPath("mask/luminance-mask.png"));
});
});
4 changes: 2 additions & 2 deletions package/src/renderer/components/imageFilters/Morphology.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const onDeclare = createDeclaration<MorphologyProps>(
const r = processRadius(Skia, radius);
const factory =
operator === "dilate"
? Skia.ImageFilter.MakeDilate
: Skia.ImageFilter.MakeErode;
? Skia.ImageFilter.MakeDilate.bind(Skia.ImageFilter)
: Skia.ImageFilter.MakeErode.bind(Skia.ImageFilter);
return factory(r.x, r.y, input);
}
);
Expand Down
4 changes: 2 additions & 2 deletions package/src/renderer/components/imageFilters/Shadow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ const onDeclare = createDeclaration<ShadowProps>(
factory = MakeInnerShadow.bind(null, Skia, shadowOnly);
} else {
factory = shadowOnly
? Skia.ImageFilter.MakeDropShadowOnly
: Skia.ImageFilter.MakeDropShadow;
? Skia.ImageFilter.MakeDropShadowOnly.bind(Skia.ImageFilter)
: Skia.ImageFilter.MakeDropShadow.bind(Skia.ImageFilter);
}
return factory(dx, dy, blur, blur, color, input);
}
Expand Down
2 changes: 1 addition & 1 deletion package/src/skia/__tests__/ImageFilter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ describe("ImageFilter", () => {
Skia.ImageFilter.MakeBlur(40, 40, TileMode.Clamp, null)
);
canvas.drawCircle(r, r, r, paint);
processResult(surface, "snapshots/image-filter/blur.png", true);
processResult(surface, "snapshots/image-filter/blur.png");
});
});
4 changes: 2 additions & 2 deletions package/src/skia/__tests__/Path.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ describe("Path", () => {
expect(moveX).toBe(0);
expect(moveY).toBe(110);
expect(lineX).toBe(100);
expect(lineY).toBe(-10);
expect(lineY).toBeCloseTo(-10);

const p4 = p2.interpolate(p1, -0.1)!;
expect(p4).not.toBeNull();
Expand All @@ -354,7 +354,7 @@ describe("Path", () => {

const ref2 = Skia.Path.Make();
ref2.moveTo(0, 110);
ref2.lineTo(100, -10);
ref2.lineTo(100, -10.000001907348633);

const p3 = interpolatePaths(-0.1, [0, 1], [p1, p2]);
expect(p3.toCmds()).toEqual(ref1.toCmds());
Expand Down
4 changes: 2 additions & 2 deletions package/src/skia/web/Host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import type { CanvasKit, EmbindEnumEntity } from "canvaskit-wasm";
import type { SkJSIInstance } from "../types";

export class NotImplementedOnRNWeb extends Error {
constructor() {
super("Not implemented on React Native Web");
constructor(msg?: string) {
super(msg ?? "Not implemented on React Native Web");
}
}

Expand Down
7 changes: 5 additions & 2 deletions package/src/skia/web/JsiSkColorFilterFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type {
BlendMode,
} from "../types";

import { ckEnum, Host, NotImplementedOnRNWeb } from "./Host";
import { ckEnum, Host } from "./Host";
import { JsiSkColorFilter } from "./JsiSkColorFilter";

export class JsiSkColorFilterFactory
Expand Down Expand Up @@ -69,6 +69,9 @@ export class JsiSkColorFilterFactory
}

MakeLumaColorFilter(): SkColorFilter {
throw new NotImplementedOnRNWeb();
return new JsiSkColorFilter(
this.CanvasKit,
this.CanvasKit.ColorFilter.MakeLuma()
);
}
}
Loading

0 comments on commit 380a110

Please sign in to comment.