react-native-skia 3.0.2 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -2
- package/apple/MetalLayerColorSpace.mm +10 -8
- package/apple/RNSkApplePlatformContext.h +12 -0
- package/apple/RNSkApplePlatformContext.mm +17 -0
- package/apple/RNSkMetalCanvasProvider.mm +4 -2
- package/apple/RNSkiaModule.mm +10 -0
- package/cpp/rnskia/RNDawnContext.h +3 -2
- package/cpp/rnskia/RNDawnUtils.h +12 -0
- package/cpp/rnskia/RNDawnWindowContext.cpp +2 -1
- package/cpp/rnskia/RNDawnWindowContext.h +15 -7
- package/cpp/rnskia/RNMetalLayerColorSpace.h +4 -2
- package/cpp/rnskia/RNSkCanvasProvider.h +18 -8
- package/cpp/rnskia/RNSkGraphiteTarget.h +20 -7
- package/cpp/rnskia/RNSkPlatformContext.h +8 -0
- package/cpp/rnskia/RNSkView.h +43 -22
- package/lib/commonjs/external/reanimated/interpolators.js +1 -1
- package/lib/commonjs/external/reanimated/interpolators.js.map +1 -1
- package/lib/commonjs/renderer/Canvas.js +1 -1
- package/lib/commonjs/renderer/Canvas.js.map +1 -1
- package/lib/module/external/reanimated/interpolators.js +1 -1
- package/lib/module/external/reanimated/interpolators.js.map +1 -1
- package/lib/module/renderer/Canvas.js +1 -1
- package/lib/module/renderer/Canvas.js.map +1 -1
- package/package.json +1 -1
- package/react-native-skia.podspec +1 -1
- package/src/external/reanimated/interpolators.ts +1 -1
- package/src/renderer/Canvas.tsx +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,23 @@ High-performance 2d Graphics for React Native using Skia
|
|
|
4
4
|
|
|
5
5
|
<img width="400" alt="skia" src="https://user-images.githubusercontent.com/306134/146549218-b7959ad9-0107-4c1c-b439-b96c780f5230.png">
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
React Native Skia brings the Skia Graphics Library to React Native. Skia serves as the graphics engine for Google Chrome and Chrome OS, Android, Flutter, Mozilla Firefox and Firefox OS, and many other products.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Getting Started
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
yarn add react-native-skia
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Checkout the full documentation [here](https://wcandillon.github.io/react-native-skia).
|
|
16
|
+
|
|
17
|
+
## v3 and v2
|
|
18
|
+
|
|
19
|
+
React Native Skia v3 renders with [Graphite](https://skia.org/docs/user/graphite/), Skia's new GPU backend, on iOS, Android (API level 26 and above), and macOS.
|
|
20
|
+
|
|
21
|
+
- To upgrade from v2 or from `@shopify/react-native-skia`, follow the [migration guide](https://wcandillon.github.io/react-native-skia/docs/getting-started/migration).
|
|
22
|
+
- v2 keeps the Ganesh backend and is still maintained. Install it with `yarn add react-native-skia@2`. Its documentation is available at [wcandillon.github.io/react-native-skia/v2](https://wcandillon.github.io/react-native-skia/v2/).
|
|
23
|
+
|
|
24
|
+
## Contributing
|
|
25
|
+
|
|
26
|
+
Documentation on the library development is available [here](https://github.com/wcandillon/react-native-skia/blob/main/packages/skia/CONTRIBUTING.md).
|
|
@@ -8,20 +8,22 @@
|
|
|
8
8
|
|
|
9
9
|
namespace RNSkia {
|
|
10
10
|
|
|
11
|
-
//
|
|
12
|
-
// (
|
|
13
|
-
//
|
|
14
|
-
// Tagging the float layer
|
|
15
|
-
//
|
|
11
|
+
// The surface holds gamma-encoded values in the gamut the view renders in
|
|
12
|
+
// (sRGB or Display P3, see DawnUtils::viewColorSpace) regardless of the
|
|
13
|
+
// texture format, so the same content must display identically on bgra8unorm
|
|
14
|
+
// and rgba16float surfaces. Tagging the float layer with the gamma-encoded
|
|
15
|
+
// extended colorspace of that gamut gives identical colors, with the extra
|
|
16
|
+
// precision of float16.
|
|
16
17
|
void applyCAMetalLayerColorSpace(void *nativeSurface,
|
|
17
|
-
wgpu::TextureFormat format
|
|
18
|
+
wgpu::TextureFormat format,
|
|
19
|
+
bool useP3ColorSpace) {
|
|
18
20
|
CALayer *layer = (__bridge CALayer *)nativeSurface;
|
|
19
21
|
if (![layer isKindOfClass:[CAMetalLayer class]]) {
|
|
20
22
|
return;
|
|
21
23
|
}
|
|
22
24
|
auto metalLayer = static_cast<CAMetalLayer *>(layer);
|
|
23
|
-
setCAMetalLayerColorSpace(
|
|
24
|
-
|
|
25
|
+
setCAMetalLayerColorSpace(
|
|
26
|
+
metalLayer, format == wgpu::TextureFormat::RGBA16Float, useP3ColorSpace);
|
|
25
27
|
// The change must be set synchronously so the first present already sees
|
|
26
28
|
// it, and it must reach the render server. On a non-main thread (RN JS or
|
|
27
29
|
// worklet runtime) the property lands in that thread's implicit
|
|
@@ -32,10 +32,21 @@ public:
|
|
|
32
32
|
// Create screenshot manager
|
|
33
33
|
_screenshotService =
|
|
34
34
|
[[ViewScreenshotService alloc] initWithViewRegistry:viewRegistry];
|
|
35
|
+
_prefersP3ColorSpace = mainScreenSupportsP3();
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
~RNSkApplePlatformContext() = default;
|
|
38
39
|
|
|
40
|
+
/**
|
|
41
|
+
Whether the main screen has a wide color gamut (Display P3). The screen is
|
|
42
|
+
asked once and the answer is kept: RNSkiaModule asks first, on the main
|
|
43
|
+
queue it is created on, so that the context (created on the JS thread)
|
|
44
|
+
only reads the answer.
|
|
45
|
+
*/
|
|
46
|
+
static bool mainScreenSupportsP3();
|
|
47
|
+
|
|
48
|
+
bool prefersP3ColorSpace() override { return _prefersP3ColorSpace; }
|
|
49
|
+
|
|
39
50
|
void runOnMainThread(std::function<void()>) override;
|
|
40
51
|
|
|
41
52
|
sk_sp<SkImage> takeScreenshotFromViewTag(size_t tag) override;
|
|
@@ -66,6 +77,7 @@ public:
|
|
|
66
77
|
|
|
67
78
|
private:
|
|
68
79
|
ViewScreenshotService *_screenshotService;
|
|
80
|
+
bool _prefersP3ColorSpace = false;
|
|
69
81
|
};
|
|
70
82
|
|
|
71
83
|
} // namespace RNSkia
|
|
@@ -242,6 +242,23 @@ void RNSkApplePlatformContext::raiseError(const std::exception &err) {
|
|
|
242
242
|
RCTFatal(RCTErrorWithMessage([NSString stringWithUTF8String:err.what()]));
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
+
bool RNSkApplePlatformContext::mainScreenSupportsP3() {
|
|
246
|
+
static bool supportsP3 = false;
|
|
247
|
+
static dispatch_once_t onceToken;
|
|
248
|
+
dispatch_once(&onceToken, ^{
|
|
249
|
+
#if !TARGET_OS_OSX
|
|
250
|
+
supportsP3 =
|
|
251
|
+
[UIScreen mainScreen].traitCollection.displayGamut == UIDisplayGamutP3;
|
|
252
|
+
#else
|
|
253
|
+
NSColorSpace *screenColorSpace = [NSScreen mainScreen].colorSpace;
|
|
254
|
+
supportsP3 =
|
|
255
|
+
screenColorSpace != nil &&
|
|
256
|
+
[screenColorSpace isEqual:[NSColorSpace displayP3ColorSpace]];
|
|
257
|
+
#endif // !TARGET_OS_OSX
|
|
258
|
+
});
|
|
259
|
+
return supportsP3;
|
|
260
|
+
}
|
|
261
|
+
|
|
245
262
|
sk_sp<SkSurface>
|
|
246
263
|
RNSkApplePlatformContext::makeOffscreenSurface(int width, int height,
|
|
247
264
|
bool useP3ColorSpace) {
|
|
@@ -94,8 +94,9 @@ void RNSkMetalCanvasProvider::setSize(int width, int height) {
|
|
|
94
94
|
// product like 1169.9999 gives the pixel size the layout means.
|
|
95
95
|
int w = static_cast<int>(std::lround(width * _context->getPixelDensity()));
|
|
96
96
|
int h = static_cast<int>(std::lround(height * _context->getPixelDensity()));
|
|
97
|
-
_ctx = RNSkia::DawnContext::getInstance().MakeWindow(
|
|
98
|
-
|
|
97
|
+
_ctx = RNSkia::DawnContext::getInstance().MakeWindow(
|
|
98
|
+
(__bridge void *)_layer, w, h, _highBitDepth,
|
|
99
|
+
_context->prefersP3ColorSpace());
|
|
99
100
|
{
|
|
100
101
|
auto *window = static_cast<RNSkia::DawnWindowContext *>(_ctx.get());
|
|
101
102
|
std::lock_guard<std::mutex> lock(_targetInfoMutex);
|
|
@@ -104,6 +105,7 @@ void RNSkMetalCanvasProvider::setSize(int width, int height) {
|
|
|
104
105
|
_targetInfo.width = window->getWidth();
|
|
105
106
|
_targetInfo.height = window->getHeight();
|
|
106
107
|
_targetInfo.colorType = window->getColorType();
|
|
108
|
+
_targetInfo.useP3ColorSpace = window->usesP3ColorSpace();
|
|
107
109
|
_targetInfo.textureInfo = window->getTextureInfo();
|
|
108
110
|
_hasTargetInfo = true;
|
|
109
111
|
}
|
package/apple/RNSkiaModule.mm
CHANGED
|
@@ -39,6 +39,16 @@ RCT_EXPORT_MODULE()
|
|
|
39
39
|
return YES;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
- (instancetype)init {
|
|
43
|
+
if (self = [super init]) {
|
|
44
|
+
// Created on the main queue (see requiresMainQueueSetup): the screen is
|
|
45
|
+
// asked for its color gamut here, where UIKit may be used. The platform
|
|
46
|
+
// context is created on the JS thread and only reads the answer.
|
|
47
|
+
RNSkia::RNSkApplePlatformContext::mainScreenSupportsP3();
|
|
48
|
+
}
|
|
49
|
+
return self;
|
|
50
|
+
}
|
|
51
|
+
|
|
42
52
|
- (void)
|
|
43
53
|
installJSIBindingsWithRuntime:(facebook::jsi::Runtime &)runtime
|
|
44
54
|
callInvoker:
|
|
@@ -406,7 +406,8 @@ public:
|
|
|
406
406
|
|
|
407
407
|
// Create onscreen surface with window
|
|
408
408
|
std::unique_ptr<WindowContext> MakeWindow(void *window, int width, int height,
|
|
409
|
-
bool highBitDepth = false
|
|
409
|
+
bool highBitDepth = false,
|
|
410
|
+
bool useP3ColorSpace = false) {
|
|
410
411
|
// 1. Create Surface
|
|
411
412
|
wgpu::SurfaceDescriptor surfaceDescriptor;
|
|
412
413
|
#ifdef __APPLE__
|
|
@@ -422,7 +423,7 @@ public:
|
|
|
422
423
|
wgpu::Instance(instance->Get()).CreateSurface(&surfaceDescriptor);
|
|
423
424
|
return std::make_unique<DawnWindowContext>(
|
|
424
425
|
getRecorder(), backendContext.fDevice, surface, window, width, height,
|
|
425
|
-
highBitDepth);
|
|
426
|
+
highBitDepth, useP3ColorSpace);
|
|
426
427
|
}
|
|
427
428
|
|
|
428
429
|
skgpu::graphite::Recorder *getRecorder() {
|
package/cpp/rnskia/RNDawnUtils.h
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
#include "dawn/native/DawnNative.h"
|
|
10
10
|
|
|
11
|
+
#include "include/core/SkColorSpace.h"
|
|
11
12
|
#include "include/core/SkColorType.h"
|
|
12
13
|
#include "include/gpu/graphite/dawn/DawnBackendContext.h"
|
|
13
14
|
#include "utils/RNSkLog.h"
|
|
@@ -42,6 +43,17 @@ static const wgpu::TextureFormat HighBitDepthTextureFormat =
|
|
|
42
43
|
wgpu::TextureFormat::RGB10A2Unorm;
|
|
43
44
|
#endif
|
|
44
45
|
|
|
46
|
+
// The color space a view renders in: Display P3 (with the sRGB transfer
|
|
47
|
+
// function) where the platform prefers it (a wide gamut display on Apple
|
|
48
|
+
// platforms, see RNSkPlatformContext::prefersP3ColorSpace), sRGB otherwise.
|
|
49
|
+
// Colors are managed either way: content looks the same in both, Display P3
|
|
50
|
+
// only adds the colors sRGB cannot represent.
|
|
51
|
+
inline sk_sp<SkColorSpace> viewColorSpace(bool useP3ColorSpace) {
|
|
52
|
+
return useP3ColorSpace ? SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB,
|
|
53
|
+
SkNamedGamut::kDisplayP3)
|
|
54
|
+
: SkColorSpace::MakeSRGB();
|
|
55
|
+
}
|
|
56
|
+
|
|
45
57
|
// Usage requested for a window texture when the surface supports it (see
|
|
46
58
|
// DawnWindowContext::supportedSurfaceUsage), and assumed for a Graphite
|
|
47
59
|
// recording made before its window exists: TextureBinding lets a render pass
|
|
@@ -29,7 +29,8 @@ bool DawnWindowContext::presentRecordings(
|
|
|
29
29
|
auto backendTex = skgpu::graphite::BackendTextures::MakeDawn(texture.Get());
|
|
30
30
|
SkSurfaceProps surfaceProps;
|
|
31
31
|
auto surface = SkSurfaces::WrapBackendTexture(
|
|
32
|
-
_recorder, backendTex,
|
|
32
|
+
_recorder, backendTex, DawnUtils::viewColorSpace(_useP3ColorSpace),
|
|
33
|
+
&surfaceProps);
|
|
33
34
|
if (!surface) {
|
|
34
35
|
return false;
|
|
35
36
|
}
|
|
@@ -30,9 +30,11 @@ class DawnWindowContext : public WindowContext {
|
|
|
30
30
|
public:
|
|
31
31
|
DawnWindowContext(skgpu::graphite::Recorder *recorder, wgpu::Device device,
|
|
32
32
|
wgpu::Surface surface, void *nativeSurface, int width,
|
|
33
|
-
int height, bool highBitDepth = false
|
|
33
|
+
int height, bool highBitDepth = false,
|
|
34
|
+
bool useP3ColorSpace = false)
|
|
34
35
|
: _recorder(recorder), _device(device), _surface(surface),
|
|
35
|
-
_nativeSurface(nativeSurface),
|
|
36
|
+
_nativeSurface(nativeSurface), _useP3ColorSpace(useP3ColorSpace),
|
|
37
|
+
_width(width), _height(height) {
|
|
36
38
|
_format = DawnUtils::PreferredTextureFormat;
|
|
37
39
|
_colorType = DawnUtils::PreferedColorType;
|
|
38
40
|
if (highBitDepth) {
|
|
@@ -59,10 +61,10 @@ public:
|
|
|
59
61
|
skgpu::graphite::SampleCount::k1, skgpu::Mipmapped::kNo, _format,
|
|
60
62
|
texture.GetUsage(), wgpu::TextureAspect::All);
|
|
61
63
|
auto backendTex = skgpu::graphite::BackendTextures::MakeDawn(texture.Get());
|
|
62
|
-
sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
|
|
63
64
|
SkSurfaceProps surfaceProps;
|
|
64
65
|
auto surface = SkSurfaces::WrapBackendTexture(
|
|
65
|
-
_recorder, backendTex, _colorType,
|
|
66
|
+
_recorder, backendTex, _colorType,
|
|
67
|
+
DawnUtils::viewColorSpace(_useP3ColorSpace), &surfaceProps);
|
|
66
68
|
return surface;
|
|
67
69
|
}
|
|
68
70
|
|
|
@@ -80,6 +82,10 @@ public:
|
|
|
80
82
|
|
|
81
83
|
SkColorType getColorType() const { return _colorType; }
|
|
82
84
|
|
|
85
|
+
// Whether the window is in Display P3 rather than sRGB: a deferred canvas
|
|
86
|
+
// must be recorded in the color space of the window it is replayed onto.
|
|
87
|
+
bool usesP3ColorSpace() const { return _useP3ColorSpace; }
|
|
88
|
+
|
|
83
89
|
// The texture description a deferred canvas must be recorded with to be
|
|
84
90
|
// replayed onto this window.
|
|
85
91
|
skgpu::graphite::TextureInfo getTextureInfo() const {
|
|
@@ -114,9 +120,10 @@ private:
|
|
|
114
120
|
#endif
|
|
115
121
|
_surface.Configure(&config);
|
|
116
122
|
#ifdef __APPLE__
|
|
117
|
-
//
|
|
118
|
-
// the
|
|
119
|
-
|
|
123
|
+
// The layer is tagged with the gamut the window renders in; float formats
|
|
124
|
+
// need the (gamma-encoded) extended variant so the values display
|
|
125
|
+
// identically to the 8-bit path.
|
|
126
|
+
applyCAMetalLayerColorSpace(_nativeSurface, _format, _useP3ColorSpace);
|
|
120
127
|
#endif
|
|
121
128
|
}
|
|
122
129
|
|
|
@@ -161,6 +168,7 @@ private:
|
|
|
161
168
|
wgpu::Device _device;
|
|
162
169
|
wgpu::Surface _surface;
|
|
163
170
|
[[maybe_unused]] void *_nativeSurface;
|
|
171
|
+
bool _useP3ColorSpace;
|
|
164
172
|
wgpu::TextureFormat _format;
|
|
165
173
|
wgpu::TextureUsage _usage = wgpu::TextureUsage::RenderAttachment;
|
|
166
174
|
SkColorType _colorType;
|
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
namespace RNSkia {
|
|
8
8
|
|
|
9
9
|
// Tags the CAMetalLayer with the colorspace matching the configured texture
|
|
10
|
-
// format. Implemented in
|
|
10
|
+
// format and the gamut the view renders in. Implemented in
|
|
11
|
+
// apple/MetalLayerColorSpace.mm.
|
|
11
12
|
void applyCAMetalLayerColorSpace(void *nativeSurface,
|
|
12
|
-
wgpu::TextureFormat format
|
|
13
|
+
wgpu::TextureFormat format,
|
|
14
|
+
bool useP3ColorSpace);
|
|
13
15
|
|
|
14
16
|
} // namespace RNSkia
|
|
15
17
|
|
|
@@ -24,15 +24,19 @@
|
|
|
24
24
|
namespace RNSkia {
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* Describes the texture a recording is replayed onto: the pixel size
|
|
28
|
-
* format of a window (or offscreen) surface. A deferred
|
|
29
|
-
* against this description, so it can be created before
|
|
30
|
-
* exists.
|
|
27
|
+
* Describes the texture a recording is replayed onto: the pixel size, the
|
|
28
|
+
* format and the color space of a window (or offscreen) surface. A deferred
|
|
29
|
+
* canvas is recorded against this description, so it can be created before
|
|
30
|
+
* the surface itself exists.
|
|
31
31
|
*/
|
|
32
32
|
struct RNSkGraphiteTargetInfo {
|
|
33
33
|
int width = 0;
|
|
34
34
|
int height = 0;
|
|
35
35
|
SkColorType colorType = kUnknown_SkColorType;
|
|
36
|
+
// Display P3 rather than sRGB (see DawnUtils::viewColorSpace). The colors
|
|
37
|
+
// of a recording are converted to the color space of its target when it is
|
|
38
|
+
// recorded, not when it is replayed.
|
|
39
|
+
bool useP3ColorSpace = false;
|
|
36
40
|
skgpu::graphite::TextureInfo textureInfo;
|
|
37
41
|
};
|
|
38
42
|
|
|
@@ -80,8 +84,8 @@ public:
|
|
|
80
84
|
/**
|
|
81
85
|
Draws an image at the origin of the target texture and presents it. Same
|
|
82
86
|
thread and return value as presentRecordings(). Used for a recording whose
|
|
83
|
-
size differs from the target's: it is replayed into a
|
|
84
|
-
|
|
87
|
+
size or color space differs from the target's: it is replayed into a
|
|
88
|
+
texture of its own first (see RNSkView::present).
|
|
85
89
|
*/
|
|
86
90
|
virtual bool presentImage(const sk_sp<SkImage> &image) = 0;
|
|
87
91
|
|
|
@@ -106,14 +110,18 @@ private:
|
|
|
106
110
|
|
|
107
111
|
/**
|
|
108
112
|
* An offscreen surface the content of a view is replayed into for a snapshot.
|
|
113
|
+
* A recording is replayed as is, so the surface takes the color space of the
|
|
114
|
+
* recordings it is meant for.
|
|
109
115
|
*/
|
|
110
116
|
class RNSkOffscreenCanvasProvider : public RNSkCanvasProvider {
|
|
111
117
|
public:
|
|
112
118
|
RNSkOffscreenCanvasProvider(
|
|
113
119
|
const std::shared_ptr<RNSkPlatformContext> &context, int width,
|
|
114
|
-
int height)
|
|
120
|
+
int height, bool useP3ColorSpace = false)
|
|
115
121
|
: _width(width), _height(height), _pd(context->getPixelDensity()),
|
|
116
|
-
|
|
122
|
+
_useP3ColorSpace(useP3ColorSpace),
|
|
123
|
+
_surface(
|
|
124
|
+
context->makeOffscreenSurface(width, height, useP3ColorSpace)) {}
|
|
117
125
|
|
|
118
126
|
virtual ~RNSkOffscreenCanvasProvider() = default;
|
|
119
127
|
|
|
@@ -175,6 +183,7 @@ public:
|
|
|
175
183
|
info->width = _width;
|
|
176
184
|
info->height = _height;
|
|
177
185
|
info->colorType = colorType;
|
|
186
|
+
info->useP3ColorSpace = _useP3ColorSpace;
|
|
178
187
|
info->textureInfo = skgpu::graphite::TextureInfos::MakeDawn(
|
|
179
188
|
skgpu::graphite::DawnTextureInfo(
|
|
180
189
|
skgpu::graphite::SampleCount::k1, skgpu::Mipmapped::kNo,
|
|
@@ -214,6 +223,7 @@ private:
|
|
|
214
223
|
int _width;
|
|
215
224
|
int _height;
|
|
216
225
|
float _pd;
|
|
226
|
+
bool _useP3ColorSpace;
|
|
217
227
|
sk_sp<SkSurface> _surface;
|
|
218
228
|
bool _cleared = false;
|
|
219
229
|
};
|
|
@@ -78,9 +78,21 @@ public:
|
|
|
78
78
|
_target.textureInfo.canBeFulfilledBy(target.textureInfo);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
/**
|
|
82
|
+
Whether the recording was made in the color space of the given target. The
|
|
83
|
+
colors of a recording are converted when it is recorded: replayed onto a
|
|
84
|
+
target in another color space, they would be read in the wrong gamut. Such
|
|
85
|
+
a recording is replayed through a texture in its own color space instead,
|
|
86
|
+
which is then drawn, and converted, onto the target (see
|
|
87
|
+
RNSkView::present).
|
|
88
|
+
*/
|
|
89
|
+
bool hasColorSpaceOf(const RNSkGraphiteTargetInfo &target) const {
|
|
90
|
+
return _target.useP3ColorSpace == target.useP3ColorSpace;
|
|
91
|
+
}
|
|
92
|
+
|
|
81
93
|
/** Whether the recording can be replayed straight onto the given target. */
|
|
82
94
|
bool isCompatibleWith(const RNSkGraphiteTargetInfo &target) const {
|
|
83
|
-
return hasSizeOf(target) && hasFormatOf(target);
|
|
95
|
+
return hasSizeOf(target) && hasFormatOf(target) && hasColorSpaceOf(target);
|
|
84
96
|
}
|
|
85
97
|
|
|
86
98
|
private:
|
|
@@ -153,9 +165,9 @@ public:
|
|
|
153
165
|
}
|
|
154
166
|
_recorder = std::move(recorder);
|
|
155
167
|
}
|
|
156
|
-
auto imageInfo =
|
|
157
|
-
|
|
158
|
-
|
|
168
|
+
auto imageInfo = SkImageInfo::Make(
|
|
169
|
+
target.width, target.height, target.colorType, kPremul_SkAlphaType,
|
|
170
|
+
DawnUtils::viewColorSpace(target.useP3ColorSpace));
|
|
159
171
|
auto *canvas =
|
|
160
172
|
_recorder->recorder->makeDeferredCanvas(imageInfo, target.textureInfo);
|
|
161
173
|
if (canvas == nullptr) {
|
|
@@ -271,9 +283,9 @@ private:
|
|
|
271
283
|
/**
|
|
272
284
|
The target to record against: the view's surface when it has one, else
|
|
273
285
|
the pixel size the platform laid the view out with, else the layout size
|
|
274
|
-
JS measured; in the last two cases with the format the
|
|
275
|
-
created with, following the same rules (see
|
|
276
|
-
SkiaView.java).
|
|
286
|
+
JS measured; in the last two cases with the format and the color space
|
|
287
|
+
the surface will be created with, following the same rules (see
|
|
288
|
+
DawnWindowContext and SkiaView.java).
|
|
277
289
|
*/
|
|
278
290
|
RNSkGraphiteTargetInfo resolveTargetInfo() {
|
|
279
291
|
std::shared_ptr<RNSkCanvasProvider> provider;
|
|
@@ -313,6 +325,7 @@ private:
|
|
|
313
325
|
}
|
|
314
326
|
info.colorType = highBitDepth ? DawnUtils::HighBitDepthColorType
|
|
315
327
|
: DawnUtils::PreferedColorType;
|
|
328
|
+
info.useP3ColorSpace = _context->prefersP3ColorSpace();
|
|
316
329
|
info.textureInfo = skgpu::graphite::TextureInfos::MakeDawn(
|
|
317
330
|
skgpu::graphite::DawnTextureInfo(
|
|
318
331
|
skgpu::graphite::SampleCount::k1, skgpu::Mipmapped::kNo,
|
|
@@ -191,6 +191,14 @@ public:
|
|
|
191
191
|
*/
|
|
192
192
|
float getPixelDensity() { return _pixelDensity; }
|
|
193
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Whether views render in Display P3 rather than sRGB: true on Apple
|
|
196
|
+
* platforms when the main screen has a wide color gamut. The answer does
|
|
197
|
+
* not change over the lifetime of the context, so a frame can be recorded
|
|
198
|
+
* for a view before its surface exists.
|
|
199
|
+
*/
|
|
200
|
+
virtual bool prefersP3ColorSpace() { return false; }
|
|
201
|
+
|
|
194
202
|
private:
|
|
195
203
|
float _pixelDensity;
|
|
196
204
|
std::shared_ptr<react::CallInvoker> _callInvoker;
|
package/cpp/rnskia/RNSkView.h
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
#pragma clang diagnostic ignored "-Wdocumentation"
|
|
23
23
|
|
|
24
24
|
#include "include/core/SkCanvas.h"
|
|
25
|
+
#include "include/core/SkColorSpace.h"
|
|
25
26
|
#include "include/core/SkImage.h"
|
|
26
27
|
#include "include/core/SkRect.h"
|
|
27
28
|
|
|
@@ -208,19 +209,34 @@ public:
|
|
|
208
209
|
/**
|
|
209
210
|
Renders the view into an offscreen surface: declarative content is
|
|
210
211
|
replayed on the calling thread with the latest values, so the snapshot
|
|
211
|
-
does not wait for a frame; otherwise the current frame is replayed.
|
|
212
|
+
does not wait for a frame; otherwise the current frame is replayed. A
|
|
213
|
+
snapshot is in sRGB whichever color space the view renders in: a frame
|
|
214
|
+
recorded in Display P3 is replayed into a surface in that color space and
|
|
215
|
+
the image is converted.
|
|
212
216
|
*/
|
|
213
217
|
sk_sp<SkImage> makeImageSnapshot(SkRect *bounds) {
|
|
214
|
-
auto provider = std::make_shared<RNSkOffscreenCanvasProvider>(
|
|
215
|
-
_platformContext, getScaledWidth(), getScaledHeight());
|
|
216
218
|
if (_producer->hasContent()) {
|
|
219
|
+
auto provider = std::make_shared<RNSkOffscreenCanvasProvider>(
|
|
220
|
+
_platformContext, getScaledWidth(), getScaledHeight());
|
|
217
221
|
if (auto *canvas = provider->getCanvas()) {
|
|
218
222
|
_producer->renderInto(canvas, _platformContext->getPixelDensity());
|
|
219
223
|
}
|
|
220
|
-
|
|
221
|
-
|
|
224
|
+
return provider->makeSnapshot(bounds);
|
|
225
|
+
}
|
|
226
|
+
auto frame = getLastFrame();
|
|
227
|
+
const bool useP3ColorSpace =
|
|
228
|
+
frame != nullptr && frame->getTarget().useP3ColorSpace;
|
|
229
|
+
auto provider = std::make_shared<RNSkOffscreenCanvasProvider>(
|
|
230
|
+
_platformContext, getScaledWidth(), getScaledHeight(), useP3ColorSpace);
|
|
231
|
+
if (frame != nullptr) {
|
|
232
|
+
renderFrame(provider, frame);
|
|
233
|
+
}
|
|
234
|
+
auto image = provider->makeSnapshot(bounds);
|
|
235
|
+
if (image != nullptr && useP3ColorSpace) {
|
|
236
|
+
// A raster image: converted on the CPU, no recorder involved.
|
|
237
|
+
image = image->makeColorSpace(nullptr, SkColorSpace::MakeSRGB(), {});
|
|
222
238
|
}
|
|
223
|
-
return
|
|
239
|
+
return image;
|
|
224
240
|
}
|
|
225
241
|
|
|
226
242
|
/** Width of the surface, in pixels. */
|
|
@@ -297,11 +313,8 @@ private:
|
|
|
297
313
|
return _target;
|
|
298
314
|
}
|
|
299
315
|
|
|
300
|
-
/**
|
|
301
|
-
|
|
302
|
-
provider (a snapshot surface). Any thread.
|
|
303
|
-
*/
|
|
304
|
-
bool renderLastFrame(const std::shared_ptr<RNSkCanvasProvider> &provider) {
|
|
316
|
+
/** The frame on screen, or the one about to be, if any. Any thread. */
|
|
317
|
+
std::shared_ptr<RNSkGraphiteRecording> getLastFrame() {
|
|
305
318
|
std::shared_ptr<RNSkGraphiteTarget> target;
|
|
306
319
|
std::shared_ptr<RNSkGraphiteRecording> recording;
|
|
307
320
|
{
|
|
@@ -314,9 +327,12 @@ private:
|
|
|
314
327
|
recording = latest;
|
|
315
328
|
}
|
|
316
329
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
330
|
+
return recording;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/** Replays a frame onto another provider (a snapshot surface). Any thread. */
|
|
334
|
+
bool renderFrame(const std::shared_ptr<RNSkCanvasProvider> &provider,
|
|
335
|
+
const std::shared_ptr<RNSkGraphiteRecording> &recording) {
|
|
320
336
|
RNSkGraphiteTargetInfo targetInfo;
|
|
321
337
|
if (!provider->getTargetInfo(&targetInfo)) {
|
|
322
338
|
return false;
|
|
@@ -335,8 +351,8 @@ private:
|
|
|
335
351
|
const RNSkGraphiteTargetInfo &targetInfo,
|
|
336
352
|
const std::vector<std::shared_ptr<RNSkGraphiteRecording>> &recordings,
|
|
337
353
|
bool remember) {
|
|
338
|
-
// Recordings of the target's size are replayed straight
|
|
339
|
-
//
|
|
354
|
+
// Recordings of the target's size and color space are replayed straight
|
|
355
|
+
// onto it, as one batch; any other goes through a texture of its own.
|
|
340
356
|
std::vector<skgpu::graphite::Recording *> batch;
|
|
341
357
|
std::shared_ptr<RNSkGraphiteRecording> last;
|
|
342
358
|
bool success = true;
|
|
@@ -355,13 +371,14 @@ private:
|
|
|
355
371
|
"different surface format");
|
|
356
372
|
continue;
|
|
357
373
|
}
|
|
358
|
-
if (recording->hasSizeOf(targetInfo)
|
|
374
|
+
if (recording->hasSizeOf(targetInfo) &&
|
|
375
|
+
recording->hasColorSpaceOf(targetInfo)) {
|
|
359
376
|
batch.push_back(recording->get());
|
|
360
377
|
last = recording;
|
|
361
378
|
continue;
|
|
362
379
|
}
|
|
363
380
|
flush();
|
|
364
|
-
if (
|
|
381
|
+
if (presentThroughTexture(provider, recording)) {
|
|
365
382
|
last = recording;
|
|
366
383
|
} else {
|
|
367
384
|
success = false;
|
|
@@ -385,13 +402,17 @@ private:
|
|
|
385
402
|
rounds the layout to pixels on its own terms), and the view may have been
|
|
386
403
|
resized since. The recording is replayed into a texture of its own size
|
|
387
404
|
and that texture is drawn onto the target, so the frame shows rather than
|
|
388
|
-
being dropped; the copy only happens while the sizes differ.
|
|
405
|
+
being dropped; the copy only happens while the sizes differ. The same goes
|
|
406
|
+
for a recording made in another color space than the target's: the
|
|
407
|
+
texture is in the color space of the recording, and drawing it converts
|
|
408
|
+
the colors.
|
|
389
409
|
*/
|
|
390
|
-
bool
|
|
391
|
-
|
|
410
|
+
bool presentThroughTexture(
|
|
411
|
+
const std::shared_ptr<RNSkCanvasProvider> &provider,
|
|
412
|
+
const std::shared_ptr<RNSkGraphiteRecording> &recording) {
|
|
392
413
|
const auto &size = recording->getTarget();
|
|
393
414
|
auto intermediate = std::make_shared<RNSkOffscreenCanvasProvider>(
|
|
394
|
-
_platformContext, size.width, size.height);
|
|
415
|
+
_platformContext, size.width, size.height, size.useP3ColorSpace);
|
|
395
416
|
RNSkGraphiteTargetInfo info;
|
|
396
417
|
if (!intermediate->getTargetInfo(&info) ||
|
|
397
418
|
!recording->isCompatibleWith(info)) {
|
|
@@ -82,7 +82,7 @@ const usePathInterpolation = (value, input, outputRange, options) => {
|
|
|
82
82
|
// Handle the case where not all paths are interpolable
|
|
83
83
|
// For example, throw an error or return early
|
|
84
84
|
throw new Error(`Not all paths in the output range are interpolable.
|
|
85
|
-
See: https://
|
|
85
|
+
See: https://wcandillon.github.io/react-native-skia/docs/animations/hooks#usepathinterpolation`);
|
|
86
86
|
}
|
|
87
87
|
return useInterpolator(() => _skia.Skia.Path.Make(), value, _animation.interpolatePaths, input, outputRange, options);
|
|
88
88
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","require","_animation","_skia","_Offscreen","_ReanimatedProxy","_interopRequireDefault","e","__esModule","default","notifyChange","value","isOnMainThread","_value","exports","usePathValue","cb","init","transform","builderInit","useMemo","Skia","PathBuilder","Make","pathInit","Path","builder","Rea","useSharedValue","path","useDerivedValue","reset","undefined","addPath","result","build","useClock","clock","callback","useCallback","info","timeSinceFirstFrame","useFrameCallback","useInterpolator","factory","interpolator","input","output","options","useAnimatedReaction","val","usePathInterpolation","outputRange","allPathsInterpolable","slice","every","isInterpolatable","Error","interpolatePaths","useVectorInterpolation","Point","interpolateVector"],"sources":["interpolators.ts"],"sourcesContent":["import type {\n ExtrapolationType,\n FrameInfo,\n SharedValue,\n} from \"react-native-reanimated\";\nimport { useCallback, useMemo } from \"react\";\n\nimport type { SkPath, SkPathBuilder, SkPoint } from \"../../skia/types\";\nimport { interpolatePaths, interpolateVector } from \"../../animation\";\nimport { Skia } from \"../../skia\";\nimport { isOnMainThread } from \"../../renderer/Offscreen\";\n\nimport Rea from \"./ReanimatedProxy\";\n\nexport const notifyChange = <T>(value: SharedValue<T>) => {\n \"worklet\";\n if (isOnMainThread()) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (value as any)._value = value.value;\n }\n};\n\n/**\n * Hook for creating animated paths using PathBuilder.\n * The callback receives a mutable PathBuilder that can be used to construct the path.\n * The resulting immutable SkPath is stored in a shared value.\n *\n * @param cb - Callback that receives the PathBuilder to construct the path\n * @param init - Optional initial path to add to the builder\n * @param transform - Optional transform function applied to the built path\n */\nexport const usePathValue = (\n cb: (builder: SkPathBuilder) => void,\n init?: SkPath,\n transform?: (path: SkPath) => SkPath\n) => {\n const builderInit = useMemo(() => Skia.PathBuilder.Make(), []);\n const pathInit = useMemo(() => Skia.Path.Make(), []);\n const builder = Rea.useSharedValue(builderInit);\n const path = Rea.useSharedValue(pathInit);\n Rea.useDerivedValue(() => {\n builder.value.reset();\n if (init !== undefined) {\n builder.value.addPath(init);\n }\n cb(builder.value);\n let result = builder.value.build();\n if (transform !== undefined) {\n result = transform(result);\n }\n path.value = result;\n notifyChange(path);\n });\n return path;\n};\n\nexport const useClock = () => {\n const clock = Rea.useSharedValue(0);\n const callback = useCallback(\n (info: FrameInfo) => {\n \"worklet\";\n clock.value = info.timeSinceFirstFrame;\n },\n [clock]\n );\n Rea.useFrameCallback(callback);\n return clock;\n};\n\n/**\n * @worklet\n */\ntype Interpolator<T> = (\n value: number,\n input: number[],\n output: T[],\n options: ExtrapolationType,\n result: T\n) => T;\n\nconst useInterpolator = <T>(\n factory: () => T,\n value: SharedValue<number>,\n interpolator: Interpolator<T>,\n input: number[],\n output: T[],\n options?: ExtrapolationType\n) => {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const init = useMemo(() => factory(), []);\n const result = Rea.useSharedValue(init);\n Rea.useAnimatedReaction(\n () => value.value,\n (val) => {\n result.value = interpolator(val, input, output, options, result.value);\n notifyChange(result);\n },\n [input, output, options]\n );\n return result;\n};\n\nexport const usePathInterpolation = (\n value: SharedValue<number>,\n input: number[],\n outputRange: SkPath[],\n options?: ExtrapolationType\n) => {\n // Check if all paths in outputRange are interpolable\n const allPathsInterpolable = outputRange\n .slice(1)\n .every((path) => outputRange[0].isInterpolatable(path));\n if (!allPathsInterpolable) {\n // Handle the case where not all paths are interpolable\n // For example, throw an error or return early\n throw new Error(\n `Not all paths in the output range are interpolable.\nSee: https://
|
|
1
|
+
{"version":3,"names":["_react","require","_animation","_skia","_Offscreen","_ReanimatedProxy","_interopRequireDefault","e","__esModule","default","notifyChange","value","isOnMainThread","_value","exports","usePathValue","cb","init","transform","builderInit","useMemo","Skia","PathBuilder","Make","pathInit","Path","builder","Rea","useSharedValue","path","useDerivedValue","reset","undefined","addPath","result","build","useClock","clock","callback","useCallback","info","timeSinceFirstFrame","useFrameCallback","useInterpolator","factory","interpolator","input","output","options","useAnimatedReaction","val","usePathInterpolation","outputRange","allPathsInterpolable","slice","every","isInterpolatable","Error","interpolatePaths","useVectorInterpolation","Point","interpolateVector"],"sources":["interpolators.ts"],"sourcesContent":["import type {\n ExtrapolationType,\n FrameInfo,\n SharedValue,\n} from \"react-native-reanimated\";\nimport { useCallback, useMemo } from \"react\";\n\nimport type { SkPath, SkPathBuilder, SkPoint } from \"../../skia/types\";\nimport { interpolatePaths, interpolateVector } from \"../../animation\";\nimport { Skia } from \"../../skia\";\nimport { isOnMainThread } from \"../../renderer/Offscreen\";\n\nimport Rea from \"./ReanimatedProxy\";\n\nexport const notifyChange = <T>(value: SharedValue<T>) => {\n \"worklet\";\n if (isOnMainThread()) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (value as any)._value = value.value;\n }\n};\n\n/**\n * Hook for creating animated paths using PathBuilder.\n * The callback receives a mutable PathBuilder that can be used to construct the path.\n * The resulting immutable SkPath is stored in a shared value.\n *\n * @param cb - Callback that receives the PathBuilder to construct the path\n * @param init - Optional initial path to add to the builder\n * @param transform - Optional transform function applied to the built path\n */\nexport const usePathValue = (\n cb: (builder: SkPathBuilder) => void,\n init?: SkPath,\n transform?: (path: SkPath) => SkPath\n) => {\n const builderInit = useMemo(() => Skia.PathBuilder.Make(), []);\n const pathInit = useMemo(() => Skia.Path.Make(), []);\n const builder = Rea.useSharedValue(builderInit);\n const path = Rea.useSharedValue(pathInit);\n Rea.useDerivedValue(() => {\n builder.value.reset();\n if (init !== undefined) {\n builder.value.addPath(init);\n }\n cb(builder.value);\n let result = builder.value.build();\n if (transform !== undefined) {\n result = transform(result);\n }\n path.value = result;\n notifyChange(path);\n });\n return path;\n};\n\nexport const useClock = () => {\n const clock = Rea.useSharedValue(0);\n const callback = useCallback(\n (info: FrameInfo) => {\n \"worklet\";\n clock.value = info.timeSinceFirstFrame;\n },\n [clock]\n );\n Rea.useFrameCallback(callback);\n return clock;\n};\n\n/**\n * @worklet\n */\ntype Interpolator<T> = (\n value: number,\n input: number[],\n output: T[],\n options: ExtrapolationType,\n result: T\n) => T;\n\nconst useInterpolator = <T>(\n factory: () => T,\n value: SharedValue<number>,\n interpolator: Interpolator<T>,\n input: number[],\n output: T[],\n options?: ExtrapolationType\n) => {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const init = useMemo(() => factory(), []);\n const result = Rea.useSharedValue(init);\n Rea.useAnimatedReaction(\n () => value.value,\n (val) => {\n result.value = interpolator(val, input, output, options, result.value);\n notifyChange(result);\n },\n [input, output, options]\n );\n return result;\n};\n\nexport const usePathInterpolation = (\n value: SharedValue<number>,\n input: number[],\n outputRange: SkPath[],\n options?: ExtrapolationType\n) => {\n // Check if all paths in outputRange are interpolable\n const allPathsInterpolable = outputRange\n .slice(1)\n .every((path) => outputRange[0].isInterpolatable(path));\n if (!allPathsInterpolable) {\n // Handle the case where not all paths are interpolable\n // For example, throw an error or return early\n throw new Error(\n `Not all paths in the output range are interpolable.\nSee: https://wcandillon.github.io/react-native-skia/docs/animations/hooks#usepathinterpolation`\n );\n }\n return useInterpolator(\n () => Skia.Path.Make(),\n value,\n interpolatePaths,\n input,\n outputRange,\n options\n );\n};\n\nexport const useVectorInterpolation = (\n value: SharedValue<number>,\n input: number[],\n outputRange: SkPoint[],\n options?: ExtrapolationType\n) =>\n useInterpolator(\n () => Skia.Point(0, 0),\n value,\n interpolateVector,\n input,\n outputRange,\n options\n );\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -56,7 +56,7 @@ const useCanvasRoot = ({
|
|
|
56
56
|
onLayout
|
|
57
57
|
}) => {
|
|
58
58
|
if (onLayout && _Platform.Platform.OS !== "web") {
|
|
59
|
-
console.error("<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://
|
|
59
|
+
console.error("<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://wcandillon.github.io/react-native-skia/docs/canvas/overview/#canvas-size");
|
|
60
60
|
}
|
|
61
61
|
const viewRef = useCanvasRefPriv(null);
|
|
62
62
|
// Native ID
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","_interopRequireWildcard","require","_ReanimatedProxy","_interopRequireDefault","_SkiaViewNativeId","_android","_SkiaViewNativeComponent","_Reconciler","_skia","_Platform","_external","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","_extends","assign","bind","arguments","length","apply","useCanvasRef","useRef","exports","useReanimatedFrame","HAS_REANIMATED_3","Rea","useFrameCallback","measure","useCanvasRefPriv","useAnimatedRef","useCanvasSize","userRef","ourRef","ref","size","setSize","useState","width","height","useLayoutEffect","current","_x","_y","useCanvasRoot","children","onSize","onLayout","Platform","OS","console","error","viewRef","nativeId","useMemo","SkiaViewNativeId","root","SkiaSGRoot","Skia","_viewRef$current","result","canvasRef","value","render","useEffect","unmount","useImperativeHandle","makeImageSnapshot","rect","SkiaViewApi","makeImageSnapshotAsync","redraw","requestRedraw","getNativeId","callback","_viewRef$current2","measureInWindow","_viewRef$current3","Canvas","opaque","highBitDepth","android","viewProps","onLayoutWeb","useCallback","nativeEvent","layout","createElement","collapsable","nativeID","androidNativeProps"],"sources":["Canvas.tsx"],"sourcesContent":["import type { FC, RefObject } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n LayoutChangeEvent,\n MeasureInWindowOnSuccessCallback,\n MeasureOnSuccessCallback,\n View,\n ViewProps,\n} from \"react-native\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\nimport Rea from \"../external/reanimated/ReanimatedProxy\";\nimport { SkiaViewNativeId } from \"../views/SkiaViewNativeId\";\nimport { androidNativeProps } from \"../views/android\";\nimport type { AndroidCanvasProps } from \"../views/types\";\nimport SkiaViewNativeComponent from \"../specs/SkiaViewNativeComponent\";\nimport type { SkImage, SkRect, SkSize } from \"../skia/types\";\nimport { SkiaSGRoot } from \"../sksg/Reconciler\";\nimport { Skia } from \"../skia\";\nimport { Platform } from \"../Platform\";\nimport { HAS_REANIMATED_3 } from \"../external\";\n\nexport interface CanvasRef extends FC<CanvasProps> {\n makeImageSnapshot(rect?: SkRect): SkImage;\n makeImageSnapshotAsync(rect?: SkRect): Promise<SkImage>;\n redraw(): void;\n getNativeId(): number;\n measure(callback: MeasureOnSuccessCallback): void;\n measureInWindow(callback: MeasureInWindowOnSuccessCallback): void;\n}\n\nexport const useCanvasRef = () => useRef<CanvasRef>(null);\n\nconst useReanimatedFrame = !HAS_REANIMATED_3 ? () => {} : Rea.useFrameCallback;\nconst measure = !HAS_REANIMATED_3 ? null : Rea.measure;\n\nconst useCanvasRefPriv: typeof useRef<View> = !HAS_REANIMATED_3\n ? useRef\n : Rea.useAnimatedRef;\n\nexport const useCanvasSize = (userRef?: RefObject<CanvasRef | null>) => {\n const ourRef = useCanvasRef();\n const ref = userRef ?? ourRef;\n const [size, setSize] = useState<SkSize>({ width: 0, height: 0 });\n useLayoutEffect(() => {\n if (ref.current) {\n ref.current.measure((_x, _y, width, height) => {\n setSize({ width, height });\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return { ref, size };\n};\n\nexport interface CanvasProps extends Omit<ViewProps, \"onLayout\"> {\n /** @deprecated Not supported on native. Use `onSize` or `useCanvasSize()` instead. */\n onLayout?: ViewProps[\"onLayout\"];\n /**\n * Declares that the canvas covers every pixel of its bounds, so nothing\n * behind it needs to show through. On Android an opaque canvas is backed by\n * a `SurfaceView` by default, the cheapest path (see `android.surfaceType`).\n * Defaults to false.\n */\n opaque?: boolean;\n onSize?: SharedValue<SkSize>;\n /**\n * Renders into a surface with more than 8 bits per channel (16-bit float on\n * iOS, 10-bit on Android) to avoid banding in subtle gradients. Colors are\n * identical to the default 8-bit surface, only with more precision (this is\n * about bit depth, not HDR). On Android the extra precision survives\n * composition only when combined with `opaque`, and the prop must be set\n * before the canvas is mounted.\n */\n highBitDepth?: boolean;\n /** Android-only rendering options. Ignored on iOS and web. */\n android?: AndroidCanvasProps;\n ref?: React.Ref<CanvasRef>;\n __destroyWebGLContextAfterRender?: boolean;\n}\n\n/**\n * What the canvas owns: the native id, the scene graph root rendered into it,\n * the `onSize` measurement and the imperative handle of the ref.\n */\nconst useCanvasRoot = ({\n children,\n onSize,\n ref,\n onLayout,\n}: Pick<CanvasProps, \"children\" | \"onSize\" | \"ref\" | \"onLayout\">) => {\n if (onLayout && Platform.OS !== \"web\") {\n console.error(\n \"<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://shopify.github.io/react-native-skia/docs/canvas/overview/#getting-the-canvas-size\"\n );\n }\n const viewRef = useCanvasRefPriv(null);\n // Native ID\n const nativeId = useMemo(() => {\n return SkiaViewNativeId.current++;\n }, []);\n\n // Root\n const root = useMemo(() => new SkiaSGRoot(Skia, nativeId), [nativeId]);\n\n useReanimatedFrame(() => {\n \"worklet\";\n if (onSize && measure) {\n const result =\n // eslint-disable-next-line no-nested-ternary\n Platform.OS === \"web\"\n ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n viewRef.current?.canvasRef\n ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n measure(viewRef.current.canvasRef)\n : { width: 0, height: 0 }\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n measure(viewRef as any);\n if (result) {\n const { width, height } = result;\n if (onSize.value.width !== width || onSize.value.height !== height) {\n onSize.value = { width, height };\n }\n }\n }\n }, !!onSize);\n\n // Render effects\n useLayoutEffect(() => {\n root.render(children);\n }, [children, root, nativeId]);\n\n useEffect(() => {\n return () => {\n root.unmount();\n };\n }, [root]);\n\n // Component methods\n useImperativeHandle(\n ref,\n () =>\n ({\n makeImageSnapshot: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshot(nativeId, rect);\n },\n makeImageSnapshotAsync: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshotAsync(nativeId, rect);\n },\n redraw: () => {\n SkiaViewApi.requestRedraw(nativeId);\n },\n getNativeId: () => {\n return nativeId;\n },\n measure: (callback) => {\n viewRef.current?.measure(callback);\n },\n measureInWindow: (callback) => {\n viewRef.current?.measureInWindow(callback);\n },\n }) as CanvasRef\n );\n return { nativeId, viewRef };\n};\n\n/**\n * The declarative canvas. Its children are rendered by Skia's own React\n * renderer; the frames are produced off the JS thread:\n *\n * - the JS thread records the scene graph into a native recorder once per\n * React commit and hands it to the view;\n * - the Reanimated UI runtime only reads the shared values into it (the one\n * step that needs a JS runtime), it never replays anything;\n * - a dedicated native thread pool replays the recorder into a Graphite\n * recording whenever the content changed, at most once per presented frame;\n * - the view presents the recording on the next vsync.\n *\n * On the web the scene is drawn into a picture on the JS thread and painted\n * on a WebGL canvas.\n */\nexport const Canvas = ({\n opaque,\n children,\n onSize,\n highBitDepth = false,\n android,\n ref,\n onLayout,\n ...viewProps\n}: CanvasProps) => {\n const { nativeId, viewRef } = useCanvasRoot({\n children,\n onSize,\n ref,\n onLayout,\n });\n\n const onLayoutWeb = useCallback(\n (e: LayoutChangeEvent) => {\n if (onLayout) {\n onLayout(e);\n }\n if (Platform.OS === \"web\" && onSize) {\n const { width, height } = e.nativeEvent.layout;\n onSize.value = { width, height };\n }\n },\n [onLayout, onSize]\n );\n return (\n <SkiaViewNativeComponent\n ref={viewRef}\n collapsable={false}\n nativeID={`${nativeId}`}\n opaque={opaque}\n highBitDepth={highBitDepth}\n {...androidNativeProps(android)}\n onLayout={\n Platform.OS === \"web\" && (onSize || onLayout) ? onLayoutWeb : onLayout\n }\n {...viewProps}\n />\n );\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_ReanimatedProxy","_interopRequireDefault","_SkiaViewNativeId","_android","_SkiaViewNativeComponent","_Reconciler","_skia","_Platform","_external","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","_extends","assign","bind","arguments","length","apply","useCanvasRef","useRef","exports","useReanimatedFrame","HAS_REANIMATED_3","Rea","useFrameCallback","measure","useCanvasRefPriv","useAnimatedRef","useCanvasSize","userRef","ourRef","ref","size","setSize","useState","width","height","useLayoutEffect","current","_x","_y","useCanvasRoot","children","onSize","onLayout","Platform","OS","console","error","viewRef","nativeId","useMemo","SkiaViewNativeId","root","SkiaSGRoot","Skia","_viewRef$current","result","canvasRef","value","render","useEffect","unmount","useImperativeHandle","makeImageSnapshot","rect","SkiaViewApi","makeImageSnapshotAsync","redraw","requestRedraw","getNativeId","callback","_viewRef$current2","measureInWindow","_viewRef$current3","Canvas","opaque","highBitDepth","android","viewProps","onLayoutWeb","useCallback","nativeEvent","layout","createElement","collapsable","nativeID","androidNativeProps"],"sources":["Canvas.tsx"],"sourcesContent":["import type { FC, RefObject } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n LayoutChangeEvent,\n MeasureInWindowOnSuccessCallback,\n MeasureOnSuccessCallback,\n View,\n ViewProps,\n} from \"react-native\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\nimport Rea from \"../external/reanimated/ReanimatedProxy\";\nimport { SkiaViewNativeId } from \"../views/SkiaViewNativeId\";\nimport { androidNativeProps } from \"../views/android\";\nimport type { AndroidCanvasProps } from \"../views/types\";\nimport SkiaViewNativeComponent from \"../specs/SkiaViewNativeComponent\";\nimport type { SkImage, SkRect, SkSize } from \"../skia/types\";\nimport { SkiaSGRoot } from \"../sksg/Reconciler\";\nimport { Skia } from \"../skia\";\nimport { Platform } from \"../Platform\";\nimport { HAS_REANIMATED_3 } from \"../external\";\n\nexport interface CanvasRef extends FC<CanvasProps> {\n makeImageSnapshot(rect?: SkRect): SkImage;\n makeImageSnapshotAsync(rect?: SkRect): Promise<SkImage>;\n redraw(): void;\n getNativeId(): number;\n measure(callback: MeasureOnSuccessCallback): void;\n measureInWindow(callback: MeasureInWindowOnSuccessCallback): void;\n}\n\nexport const useCanvasRef = () => useRef<CanvasRef>(null);\n\nconst useReanimatedFrame = !HAS_REANIMATED_3 ? () => {} : Rea.useFrameCallback;\nconst measure = !HAS_REANIMATED_3 ? null : Rea.measure;\n\nconst useCanvasRefPriv: typeof useRef<View> = !HAS_REANIMATED_3\n ? useRef\n : Rea.useAnimatedRef;\n\nexport const useCanvasSize = (userRef?: RefObject<CanvasRef | null>) => {\n const ourRef = useCanvasRef();\n const ref = userRef ?? ourRef;\n const [size, setSize] = useState<SkSize>({ width: 0, height: 0 });\n useLayoutEffect(() => {\n if (ref.current) {\n ref.current.measure((_x, _y, width, height) => {\n setSize({ width, height });\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return { ref, size };\n};\n\nexport interface CanvasProps extends Omit<ViewProps, \"onLayout\"> {\n /** @deprecated Not supported on native. Use `onSize` or `useCanvasSize()` instead. */\n onLayout?: ViewProps[\"onLayout\"];\n /**\n * Declares that the canvas covers every pixel of its bounds, so nothing\n * behind it needs to show through. On Android an opaque canvas is backed by\n * a `SurfaceView` by default, the cheapest path (see `android.surfaceType`).\n * Defaults to false.\n */\n opaque?: boolean;\n onSize?: SharedValue<SkSize>;\n /**\n * Renders into a surface with more than 8 bits per channel (16-bit float on\n * iOS, 10-bit on Android) to avoid banding in subtle gradients. Colors are\n * identical to the default 8-bit surface, only with more precision (this is\n * about bit depth, not HDR). On Android the extra precision survives\n * composition only when combined with `opaque`, and the prop must be set\n * before the canvas is mounted.\n */\n highBitDepth?: boolean;\n /** Android-only rendering options. Ignored on iOS and web. */\n android?: AndroidCanvasProps;\n ref?: React.Ref<CanvasRef>;\n __destroyWebGLContextAfterRender?: boolean;\n}\n\n/**\n * What the canvas owns: the native id, the scene graph root rendered into it,\n * the `onSize` measurement and the imperative handle of the ref.\n */\nconst useCanvasRoot = ({\n children,\n onSize,\n ref,\n onLayout,\n}: Pick<CanvasProps, \"children\" | \"onSize\" | \"ref\" | \"onLayout\">) => {\n if (onLayout && Platform.OS !== \"web\") {\n console.error(\n \"<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://wcandillon.github.io/react-native-skia/docs/canvas/overview/#canvas-size\"\n );\n }\n const viewRef = useCanvasRefPriv(null);\n // Native ID\n const nativeId = useMemo(() => {\n return SkiaViewNativeId.current++;\n }, []);\n\n // Root\n const root = useMemo(() => new SkiaSGRoot(Skia, nativeId), [nativeId]);\n\n useReanimatedFrame(() => {\n \"worklet\";\n if (onSize && measure) {\n const result =\n // eslint-disable-next-line no-nested-ternary\n Platform.OS === \"web\"\n ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n viewRef.current?.canvasRef\n ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n measure(viewRef.current.canvasRef)\n : { width: 0, height: 0 }\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n measure(viewRef as any);\n if (result) {\n const { width, height } = result;\n if (onSize.value.width !== width || onSize.value.height !== height) {\n onSize.value = { width, height };\n }\n }\n }\n }, !!onSize);\n\n // Render effects\n useLayoutEffect(() => {\n root.render(children);\n }, [children, root, nativeId]);\n\n useEffect(() => {\n return () => {\n root.unmount();\n };\n }, [root]);\n\n // Component methods\n useImperativeHandle(\n ref,\n () =>\n ({\n makeImageSnapshot: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshot(nativeId, rect);\n },\n makeImageSnapshotAsync: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshotAsync(nativeId, rect);\n },\n redraw: () => {\n SkiaViewApi.requestRedraw(nativeId);\n },\n getNativeId: () => {\n return nativeId;\n },\n measure: (callback) => {\n viewRef.current?.measure(callback);\n },\n measureInWindow: (callback) => {\n viewRef.current?.measureInWindow(callback);\n },\n }) as CanvasRef\n );\n return { nativeId, viewRef };\n};\n\n/**\n * The declarative canvas. Its children are rendered by Skia's own React\n * renderer; the frames are produced off the JS thread:\n *\n * - the JS thread records the scene graph into a native recorder once per\n * React commit and hands it to the view;\n * - the Reanimated UI runtime only reads the shared values into it (the one\n * step that needs a JS runtime), it never replays anything;\n * - a dedicated native thread pool replays the recorder into a Graphite\n * recording whenever the content changed, at most once per presented frame;\n * - the view presents the recording on the next vsync.\n *\n * On the web the scene is drawn into a picture on the JS thread and painted\n * on a WebGL canvas.\n */\nexport const Canvas = ({\n opaque,\n children,\n onSize,\n highBitDepth = false,\n android,\n ref,\n onLayout,\n ...viewProps\n}: CanvasProps) => {\n const { nativeId, viewRef } = useCanvasRoot({\n children,\n onSize,\n ref,\n onLayout,\n });\n\n const onLayoutWeb = useCallback(\n (e: LayoutChangeEvent) => {\n if (onLayout) {\n onLayout(e);\n }\n if (Platform.OS === \"web\" && onSize) {\n const { width, height } = e.nativeEvent.layout;\n onSize.value = { width, height };\n }\n },\n [onLayout, onSize]\n );\n return (\n <SkiaViewNativeComponent\n ref={viewRef}\n collapsable={false}\n nativeID={`${nativeId}`}\n opaque={opaque}\n highBitDepth={highBitDepth}\n {...androidNativeProps(android)}\n onLayout={\n Platform.OS === \"web\" && (onSize || onLayout) ? onLayoutWeb : onLayout\n }\n {...viewProps}\n />\n );\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -73,7 +73,7 @@ export const usePathInterpolation = (value, input, outputRange, options) => {
|
|
|
73
73
|
// Handle the case where not all paths are interpolable
|
|
74
74
|
// For example, throw an error or return early
|
|
75
75
|
throw new Error(`Not all paths in the output range are interpolable.
|
|
76
|
-
See: https://
|
|
76
|
+
See: https://wcandillon.github.io/react-native-skia/docs/animations/hooks#usepathinterpolation`);
|
|
77
77
|
}
|
|
78
78
|
return useInterpolator(() => Skia.Path.Make(), value, interpolatePaths, input, outputRange, options);
|
|
79
79
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useMemo","interpolatePaths","interpolateVector","Skia","isOnMainThread","Rea","notifyChange","value","_value","usePathValue","cb","init","transform","builderInit","PathBuilder","Make","pathInit","Path","builder","useSharedValue","path","useDerivedValue","reset","undefined","addPath","result","build","useClock","clock","callback","info","timeSinceFirstFrame","useFrameCallback","useInterpolator","factory","interpolator","input","output","options","useAnimatedReaction","val","usePathInterpolation","outputRange","allPathsInterpolable","slice","every","isInterpolatable","Error","useVectorInterpolation","Point"],"sources":["interpolators.ts"],"sourcesContent":["import type {\n ExtrapolationType,\n FrameInfo,\n SharedValue,\n} from \"react-native-reanimated\";\nimport { useCallback, useMemo } from \"react\";\n\nimport type { SkPath, SkPathBuilder, SkPoint } from \"../../skia/types\";\nimport { interpolatePaths, interpolateVector } from \"../../animation\";\nimport { Skia } from \"../../skia\";\nimport { isOnMainThread } from \"../../renderer/Offscreen\";\n\nimport Rea from \"./ReanimatedProxy\";\n\nexport const notifyChange = <T>(value: SharedValue<T>) => {\n \"worklet\";\n if (isOnMainThread()) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (value as any)._value = value.value;\n }\n};\n\n/**\n * Hook for creating animated paths using PathBuilder.\n * The callback receives a mutable PathBuilder that can be used to construct the path.\n * The resulting immutable SkPath is stored in a shared value.\n *\n * @param cb - Callback that receives the PathBuilder to construct the path\n * @param init - Optional initial path to add to the builder\n * @param transform - Optional transform function applied to the built path\n */\nexport const usePathValue = (\n cb: (builder: SkPathBuilder) => void,\n init?: SkPath,\n transform?: (path: SkPath) => SkPath\n) => {\n const builderInit = useMemo(() => Skia.PathBuilder.Make(), []);\n const pathInit = useMemo(() => Skia.Path.Make(), []);\n const builder = Rea.useSharedValue(builderInit);\n const path = Rea.useSharedValue(pathInit);\n Rea.useDerivedValue(() => {\n builder.value.reset();\n if (init !== undefined) {\n builder.value.addPath(init);\n }\n cb(builder.value);\n let result = builder.value.build();\n if (transform !== undefined) {\n result = transform(result);\n }\n path.value = result;\n notifyChange(path);\n });\n return path;\n};\n\nexport const useClock = () => {\n const clock = Rea.useSharedValue(0);\n const callback = useCallback(\n (info: FrameInfo) => {\n \"worklet\";\n clock.value = info.timeSinceFirstFrame;\n },\n [clock]\n );\n Rea.useFrameCallback(callback);\n return clock;\n};\n\n/**\n * @worklet\n */\ntype Interpolator<T> = (\n value: number,\n input: number[],\n output: T[],\n options: ExtrapolationType,\n result: T\n) => T;\n\nconst useInterpolator = <T>(\n factory: () => T,\n value: SharedValue<number>,\n interpolator: Interpolator<T>,\n input: number[],\n output: T[],\n options?: ExtrapolationType\n) => {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const init = useMemo(() => factory(), []);\n const result = Rea.useSharedValue(init);\n Rea.useAnimatedReaction(\n () => value.value,\n (val) => {\n result.value = interpolator(val, input, output, options, result.value);\n notifyChange(result);\n },\n [input, output, options]\n );\n return result;\n};\n\nexport const usePathInterpolation = (\n value: SharedValue<number>,\n input: number[],\n outputRange: SkPath[],\n options?: ExtrapolationType\n) => {\n // Check if all paths in outputRange are interpolable\n const allPathsInterpolable = outputRange\n .slice(1)\n .every((path) => outputRange[0].isInterpolatable(path));\n if (!allPathsInterpolable) {\n // Handle the case where not all paths are interpolable\n // For example, throw an error or return early\n throw new Error(\n `Not all paths in the output range are interpolable.\nSee: https://
|
|
1
|
+
{"version":3,"names":["useCallback","useMemo","interpolatePaths","interpolateVector","Skia","isOnMainThread","Rea","notifyChange","value","_value","usePathValue","cb","init","transform","builderInit","PathBuilder","Make","pathInit","Path","builder","useSharedValue","path","useDerivedValue","reset","undefined","addPath","result","build","useClock","clock","callback","info","timeSinceFirstFrame","useFrameCallback","useInterpolator","factory","interpolator","input","output","options","useAnimatedReaction","val","usePathInterpolation","outputRange","allPathsInterpolable","slice","every","isInterpolatable","Error","useVectorInterpolation","Point"],"sources":["interpolators.ts"],"sourcesContent":["import type {\n ExtrapolationType,\n FrameInfo,\n SharedValue,\n} from \"react-native-reanimated\";\nimport { useCallback, useMemo } from \"react\";\n\nimport type { SkPath, SkPathBuilder, SkPoint } from \"../../skia/types\";\nimport { interpolatePaths, interpolateVector } from \"../../animation\";\nimport { Skia } from \"../../skia\";\nimport { isOnMainThread } from \"../../renderer/Offscreen\";\n\nimport Rea from \"./ReanimatedProxy\";\n\nexport const notifyChange = <T>(value: SharedValue<T>) => {\n \"worklet\";\n if (isOnMainThread()) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (value as any)._value = value.value;\n }\n};\n\n/**\n * Hook for creating animated paths using PathBuilder.\n * The callback receives a mutable PathBuilder that can be used to construct the path.\n * The resulting immutable SkPath is stored in a shared value.\n *\n * @param cb - Callback that receives the PathBuilder to construct the path\n * @param init - Optional initial path to add to the builder\n * @param transform - Optional transform function applied to the built path\n */\nexport const usePathValue = (\n cb: (builder: SkPathBuilder) => void,\n init?: SkPath,\n transform?: (path: SkPath) => SkPath\n) => {\n const builderInit = useMemo(() => Skia.PathBuilder.Make(), []);\n const pathInit = useMemo(() => Skia.Path.Make(), []);\n const builder = Rea.useSharedValue(builderInit);\n const path = Rea.useSharedValue(pathInit);\n Rea.useDerivedValue(() => {\n builder.value.reset();\n if (init !== undefined) {\n builder.value.addPath(init);\n }\n cb(builder.value);\n let result = builder.value.build();\n if (transform !== undefined) {\n result = transform(result);\n }\n path.value = result;\n notifyChange(path);\n });\n return path;\n};\n\nexport const useClock = () => {\n const clock = Rea.useSharedValue(0);\n const callback = useCallback(\n (info: FrameInfo) => {\n \"worklet\";\n clock.value = info.timeSinceFirstFrame;\n },\n [clock]\n );\n Rea.useFrameCallback(callback);\n return clock;\n};\n\n/**\n * @worklet\n */\ntype Interpolator<T> = (\n value: number,\n input: number[],\n output: T[],\n options: ExtrapolationType,\n result: T\n) => T;\n\nconst useInterpolator = <T>(\n factory: () => T,\n value: SharedValue<number>,\n interpolator: Interpolator<T>,\n input: number[],\n output: T[],\n options?: ExtrapolationType\n) => {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const init = useMemo(() => factory(), []);\n const result = Rea.useSharedValue(init);\n Rea.useAnimatedReaction(\n () => value.value,\n (val) => {\n result.value = interpolator(val, input, output, options, result.value);\n notifyChange(result);\n },\n [input, output, options]\n );\n return result;\n};\n\nexport const usePathInterpolation = (\n value: SharedValue<number>,\n input: number[],\n outputRange: SkPath[],\n options?: ExtrapolationType\n) => {\n // Check if all paths in outputRange are interpolable\n const allPathsInterpolable = outputRange\n .slice(1)\n .every((path) => outputRange[0].isInterpolatable(path));\n if (!allPathsInterpolable) {\n // Handle the case where not all paths are interpolable\n // For example, throw an error or return early\n throw new Error(\n `Not all paths in the output range are interpolable.\nSee: https://wcandillon.github.io/react-native-skia/docs/animations/hooks#usepathinterpolation`\n );\n }\n return useInterpolator(\n () => Skia.Path.Make(),\n value,\n interpolatePaths,\n input,\n outputRange,\n options\n );\n};\n\nexport const useVectorInterpolation = (\n value: SharedValue<number>,\n input: number[],\n outputRange: SkPoint[],\n options?: ExtrapolationType\n) =>\n useInterpolator(\n () => Skia.Point(0, 0),\n value,\n interpolateVector,\n input,\n outputRange,\n options\n );\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -46,7 +46,7 @@ const useCanvasRoot = ({
|
|
|
46
46
|
onLayout
|
|
47
47
|
}) => {
|
|
48
48
|
if (onLayout && Platform.OS !== "web") {
|
|
49
|
-
console.error("<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://
|
|
49
|
+
console.error("<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://wcandillon.github.io/react-native-skia/docs/canvas/overview/#canvas-size");
|
|
50
50
|
}
|
|
51
51
|
const viewRef = useCanvasRefPriv(null);
|
|
52
52
|
// Native ID
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useCallback","useEffect","useImperativeHandle","useLayoutEffect","useMemo","useRef","useState","Rea","SkiaViewNativeId","androidNativeProps","SkiaViewNativeComponent","SkiaSGRoot","Skia","Platform","HAS_REANIMATED_3","useCanvasRef","useReanimatedFrame","useFrameCallback","measure","useCanvasRefPriv","useAnimatedRef","useCanvasSize","userRef","ourRef","ref","size","setSize","width","height","current","_x","_y","useCanvasRoot","children","onSize","onLayout","OS","console","error","viewRef","nativeId","root","_viewRef$current","result","canvasRef","value","render","unmount","makeImageSnapshot","rect","SkiaViewApi","makeImageSnapshotAsync","redraw","requestRedraw","getNativeId","callback","_viewRef$current2","measureInWindow","_viewRef$current3","Canvas","opaque","highBitDepth","android","viewProps","onLayoutWeb","e","nativeEvent","layout","createElement","_extends","collapsable","nativeID"],"sources":["Canvas.tsx"],"sourcesContent":["import type { FC, RefObject } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n LayoutChangeEvent,\n MeasureInWindowOnSuccessCallback,\n MeasureOnSuccessCallback,\n View,\n ViewProps,\n} from \"react-native\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\nimport Rea from \"../external/reanimated/ReanimatedProxy\";\nimport { SkiaViewNativeId } from \"../views/SkiaViewNativeId\";\nimport { androidNativeProps } from \"../views/android\";\nimport type { AndroidCanvasProps } from \"../views/types\";\nimport SkiaViewNativeComponent from \"../specs/SkiaViewNativeComponent\";\nimport type { SkImage, SkRect, SkSize } from \"../skia/types\";\nimport { SkiaSGRoot } from \"../sksg/Reconciler\";\nimport { Skia } from \"../skia\";\nimport { Platform } from \"../Platform\";\nimport { HAS_REANIMATED_3 } from \"../external\";\n\nexport interface CanvasRef extends FC<CanvasProps> {\n makeImageSnapshot(rect?: SkRect): SkImage;\n makeImageSnapshotAsync(rect?: SkRect): Promise<SkImage>;\n redraw(): void;\n getNativeId(): number;\n measure(callback: MeasureOnSuccessCallback): void;\n measureInWindow(callback: MeasureInWindowOnSuccessCallback): void;\n}\n\nexport const useCanvasRef = () => useRef<CanvasRef>(null);\n\nconst useReanimatedFrame = !HAS_REANIMATED_3 ? () => {} : Rea.useFrameCallback;\nconst measure = !HAS_REANIMATED_3 ? null : Rea.measure;\n\nconst useCanvasRefPriv: typeof useRef<View> = !HAS_REANIMATED_3\n ? useRef\n : Rea.useAnimatedRef;\n\nexport const useCanvasSize = (userRef?: RefObject<CanvasRef | null>) => {\n const ourRef = useCanvasRef();\n const ref = userRef ?? ourRef;\n const [size, setSize] = useState<SkSize>({ width: 0, height: 0 });\n useLayoutEffect(() => {\n if (ref.current) {\n ref.current.measure((_x, _y, width, height) => {\n setSize({ width, height });\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return { ref, size };\n};\n\nexport interface CanvasProps extends Omit<ViewProps, \"onLayout\"> {\n /** @deprecated Not supported on native. Use `onSize` or `useCanvasSize()` instead. */\n onLayout?: ViewProps[\"onLayout\"];\n /**\n * Declares that the canvas covers every pixel of its bounds, so nothing\n * behind it needs to show through. On Android an opaque canvas is backed by\n * a `SurfaceView` by default, the cheapest path (see `android.surfaceType`).\n * Defaults to false.\n */\n opaque?: boolean;\n onSize?: SharedValue<SkSize>;\n /**\n * Renders into a surface with more than 8 bits per channel (16-bit float on\n * iOS, 10-bit on Android) to avoid banding in subtle gradients. Colors are\n * identical to the default 8-bit surface, only with more precision (this is\n * about bit depth, not HDR). On Android the extra precision survives\n * composition only when combined with `opaque`, and the prop must be set\n * before the canvas is mounted.\n */\n highBitDepth?: boolean;\n /** Android-only rendering options. Ignored on iOS and web. */\n android?: AndroidCanvasProps;\n ref?: React.Ref<CanvasRef>;\n __destroyWebGLContextAfterRender?: boolean;\n}\n\n/**\n * What the canvas owns: the native id, the scene graph root rendered into it,\n * the `onSize` measurement and the imperative handle of the ref.\n */\nconst useCanvasRoot = ({\n children,\n onSize,\n ref,\n onLayout,\n}: Pick<CanvasProps, \"children\" | \"onSize\" | \"ref\" | \"onLayout\">) => {\n if (onLayout && Platform.OS !== \"web\") {\n console.error(\n \"<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://shopify.github.io/react-native-skia/docs/canvas/overview/#getting-the-canvas-size\"\n );\n }\n const viewRef = useCanvasRefPriv(null);\n // Native ID\n const nativeId = useMemo(() => {\n return SkiaViewNativeId.current++;\n }, []);\n\n // Root\n const root = useMemo(() => new SkiaSGRoot(Skia, nativeId), [nativeId]);\n\n useReanimatedFrame(() => {\n \"worklet\";\n if (onSize && measure) {\n const result =\n // eslint-disable-next-line no-nested-ternary\n Platform.OS === \"web\"\n ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n viewRef.current?.canvasRef\n ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n measure(viewRef.current.canvasRef)\n : { width: 0, height: 0 }\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n measure(viewRef as any);\n if (result) {\n const { width, height } = result;\n if (onSize.value.width !== width || onSize.value.height !== height) {\n onSize.value = { width, height };\n }\n }\n }\n }, !!onSize);\n\n // Render effects\n useLayoutEffect(() => {\n root.render(children);\n }, [children, root, nativeId]);\n\n useEffect(() => {\n return () => {\n root.unmount();\n };\n }, [root]);\n\n // Component methods\n useImperativeHandle(\n ref,\n () =>\n ({\n makeImageSnapshot: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshot(nativeId, rect);\n },\n makeImageSnapshotAsync: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshotAsync(nativeId, rect);\n },\n redraw: () => {\n SkiaViewApi.requestRedraw(nativeId);\n },\n getNativeId: () => {\n return nativeId;\n },\n measure: (callback) => {\n viewRef.current?.measure(callback);\n },\n measureInWindow: (callback) => {\n viewRef.current?.measureInWindow(callback);\n },\n }) as CanvasRef\n );\n return { nativeId, viewRef };\n};\n\n/**\n * The declarative canvas. Its children are rendered by Skia's own React\n * renderer; the frames are produced off the JS thread:\n *\n * - the JS thread records the scene graph into a native recorder once per\n * React commit and hands it to the view;\n * - the Reanimated UI runtime only reads the shared values into it (the one\n * step that needs a JS runtime), it never replays anything;\n * - a dedicated native thread pool replays the recorder into a Graphite\n * recording whenever the content changed, at most once per presented frame;\n * - the view presents the recording on the next vsync.\n *\n * On the web the scene is drawn into a picture on the JS thread and painted\n * on a WebGL canvas.\n */\nexport const Canvas = ({\n opaque,\n children,\n onSize,\n highBitDepth = false,\n android,\n ref,\n onLayout,\n ...viewProps\n}: CanvasProps) => {\n const { nativeId, viewRef } = useCanvasRoot({\n children,\n onSize,\n ref,\n onLayout,\n });\n\n const onLayoutWeb = useCallback(\n (e: LayoutChangeEvent) => {\n if (onLayout) {\n onLayout(e);\n }\n if (Platform.OS === \"web\" && onSize) {\n const { width, height } = e.nativeEvent.layout;\n onSize.value = { width, height };\n }\n },\n [onLayout, onSize]\n );\n return (\n <SkiaViewNativeComponent\n ref={viewRef}\n collapsable={false}\n nativeID={`${nativeId}`}\n opaque={opaque}\n highBitDepth={highBitDepth}\n {...androidNativeProps(android)}\n onLayout={\n Platform.OS === \"web\" && (onSize || onLayout) ? onLayoutWeb : onLayout\n }\n {...viewProps}\n />\n );\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["React","useCallback","useEffect","useImperativeHandle","useLayoutEffect","useMemo","useRef","useState","Rea","SkiaViewNativeId","androidNativeProps","SkiaViewNativeComponent","SkiaSGRoot","Skia","Platform","HAS_REANIMATED_3","useCanvasRef","useReanimatedFrame","useFrameCallback","measure","useCanvasRefPriv","useAnimatedRef","useCanvasSize","userRef","ourRef","ref","size","setSize","width","height","current","_x","_y","useCanvasRoot","children","onSize","onLayout","OS","console","error","viewRef","nativeId","root","_viewRef$current","result","canvasRef","value","render","unmount","makeImageSnapshot","rect","SkiaViewApi","makeImageSnapshotAsync","redraw","requestRedraw","getNativeId","callback","_viewRef$current2","measureInWindow","_viewRef$current3","Canvas","opaque","highBitDepth","android","viewProps","onLayoutWeb","e","nativeEvent","layout","createElement","_extends","collapsable","nativeID"],"sources":["Canvas.tsx"],"sourcesContent":["import type { FC, RefObject } from \"react\";\nimport React, {\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n LayoutChangeEvent,\n MeasureInWindowOnSuccessCallback,\n MeasureOnSuccessCallback,\n View,\n ViewProps,\n} from \"react-native\";\nimport type { SharedValue } from \"react-native-reanimated\";\n\nimport Rea from \"../external/reanimated/ReanimatedProxy\";\nimport { SkiaViewNativeId } from \"../views/SkiaViewNativeId\";\nimport { androidNativeProps } from \"../views/android\";\nimport type { AndroidCanvasProps } from \"../views/types\";\nimport SkiaViewNativeComponent from \"../specs/SkiaViewNativeComponent\";\nimport type { SkImage, SkRect, SkSize } from \"../skia/types\";\nimport { SkiaSGRoot } from \"../sksg/Reconciler\";\nimport { Skia } from \"../skia\";\nimport { Platform } from \"../Platform\";\nimport { HAS_REANIMATED_3 } from \"../external\";\n\nexport interface CanvasRef extends FC<CanvasProps> {\n makeImageSnapshot(rect?: SkRect): SkImage;\n makeImageSnapshotAsync(rect?: SkRect): Promise<SkImage>;\n redraw(): void;\n getNativeId(): number;\n measure(callback: MeasureOnSuccessCallback): void;\n measureInWindow(callback: MeasureInWindowOnSuccessCallback): void;\n}\n\nexport const useCanvasRef = () => useRef<CanvasRef>(null);\n\nconst useReanimatedFrame = !HAS_REANIMATED_3 ? () => {} : Rea.useFrameCallback;\nconst measure = !HAS_REANIMATED_3 ? null : Rea.measure;\n\nconst useCanvasRefPriv: typeof useRef<View> = !HAS_REANIMATED_3\n ? useRef\n : Rea.useAnimatedRef;\n\nexport const useCanvasSize = (userRef?: RefObject<CanvasRef | null>) => {\n const ourRef = useCanvasRef();\n const ref = userRef ?? ourRef;\n const [size, setSize] = useState<SkSize>({ width: 0, height: 0 });\n useLayoutEffect(() => {\n if (ref.current) {\n ref.current.measure((_x, _y, width, height) => {\n setSize({ width, height });\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n return { ref, size };\n};\n\nexport interface CanvasProps extends Omit<ViewProps, \"onLayout\"> {\n /** @deprecated Not supported on native. Use `onSize` or `useCanvasSize()` instead. */\n onLayout?: ViewProps[\"onLayout\"];\n /**\n * Declares that the canvas covers every pixel of its bounds, so nothing\n * behind it needs to show through. On Android an opaque canvas is backed by\n * a `SurfaceView` by default, the cheapest path (see `android.surfaceType`).\n * Defaults to false.\n */\n opaque?: boolean;\n onSize?: SharedValue<SkSize>;\n /**\n * Renders into a surface with more than 8 bits per channel (16-bit float on\n * iOS, 10-bit on Android) to avoid banding in subtle gradients. Colors are\n * identical to the default 8-bit surface, only with more precision (this is\n * about bit depth, not HDR). On Android the extra precision survives\n * composition only when combined with `opaque`, and the prop must be set\n * before the canvas is mounted.\n */\n highBitDepth?: boolean;\n /** Android-only rendering options. Ignored on iOS and web. */\n android?: AndroidCanvasProps;\n ref?: React.Ref<CanvasRef>;\n __destroyWebGLContextAfterRender?: boolean;\n}\n\n/**\n * What the canvas owns: the native id, the scene graph root rendered into it,\n * the `onSize` measurement and the imperative handle of the ref.\n */\nconst useCanvasRoot = ({\n children,\n onSize,\n ref,\n onLayout,\n}: Pick<CanvasProps, \"children\" | \"onSize\" | \"ref\" | \"onLayout\">) => {\n if (onLayout && Platform.OS !== \"web\") {\n console.error(\n \"<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://wcandillon.github.io/react-native-skia/docs/canvas/overview/#canvas-size\"\n );\n }\n const viewRef = useCanvasRefPriv(null);\n // Native ID\n const nativeId = useMemo(() => {\n return SkiaViewNativeId.current++;\n }, []);\n\n // Root\n const root = useMemo(() => new SkiaSGRoot(Skia, nativeId), [nativeId]);\n\n useReanimatedFrame(() => {\n \"worklet\";\n if (onSize && measure) {\n const result =\n // eslint-disable-next-line no-nested-ternary\n Platform.OS === \"web\"\n ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n viewRef.current?.canvasRef\n ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n measure(viewRef.current.canvasRef)\n : { width: 0, height: 0 }\n : // eslint-disable-next-line @typescript-eslint/no-explicit-any\n measure(viewRef as any);\n if (result) {\n const { width, height } = result;\n if (onSize.value.width !== width || onSize.value.height !== height) {\n onSize.value = { width, height };\n }\n }\n }\n }, !!onSize);\n\n // Render effects\n useLayoutEffect(() => {\n root.render(children);\n }, [children, root, nativeId]);\n\n useEffect(() => {\n return () => {\n root.unmount();\n };\n }, [root]);\n\n // Component methods\n useImperativeHandle(\n ref,\n () =>\n ({\n makeImageSnapshot: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshot(nativeId, rect);\n },\n makeImageSnapshotAsync: (rect?: SkRect) => {\n return SkiaViewApi.makeImageSnapshotAsync(nativeId, rect);\n },\n redraw: () => {\n SkiaViewApi.requestRedraw(nativeId);\n },\n getNativeId: () => {\n return nativeId;\n },\n measure: (callback) => {\n viewRef.current?.measure(callback);\n },\n measureInWindow: (callback) => {\n viewRef.current?.measureInWindow(callback);\n },\n }) as CanvasRef\n );\n return { nativeId, viewRef };\n};\n\n/**\n * The declarative canvas. Its children are rendered by Skia's own React\n * renderer; the frames are produced off the JS thread:\n *\n * - the JS thread records the scene graph into a native recorder once per\n * React commit and hands it to the view;\n * - the Reanimated UI runtime only reads the shared values into it (the one\n * step that needs a JS runtime), it never replays anything;\n * - a dedicated native thread pool replays the recorder into a Graphite\n * recording whenever the content changed, at most once per presented frame;\n * - the view presents the recording on the next vsync.\n *\n * On the web the scene is drawn into a picture on the JS thread and painted\n * on a WebGL canvas.\n */\nexport const Canvas = ({\n opaque,\n children,\n onSize,\n highBitDepth = false,\n android,\n ref,\n onLayout,\n ...viewProps\n}: CanvasProps) => {\n const { nativeId, viewRef } = useCanvasRoot({\n children,\n onSize,\n ref,\n onLayout,\n });\n\n const onLayoutWeb = useCallback(\n (e: LayoutChangeEvent) => {\n if (onLayout) {\n onLayout(e);\n }\n if (Platform.OS === \"web\" && onSize) {\n const { width, height } = e.nativeEvent.layout;\n onSize.value = { width, height };\n }\n },\n [onLayout, onSize]\n );\n return (\n <SkiaViewNativeComponent\n ref={viewRef}\n collapsable={false}\n nativeID={`${nativeId}`}\n opaque={opaque}\n highBitDepth={highBitDepth}\n {...androidNativeProps(android)}\n onLayout={\n Platform.OS === \"web\" && (onSize || onLayout) ? onLayoutWeb : onLayout\n }\n {...viewProps}\n />\n );\n};\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"setup-skia-web": "scripts/setup-canvaskit.js"
|
|
9
9
|
},
|
|
10
10
|
"title": "React Native Skia",
|
|
11
|
-
"version": "3.0.
|
|
11
|
+
"version": "3.0.3",
|
|
12
12
|
"description": "High-performance React Native Graphics using Skia",
|
|
13
13
|
"main": "lib/module/index.js",
|
|
14
14
|
"react-native": "src/index.ts",
|
|
@@ -163,7 +163,7 @@ Pod::Spec.new do |s|
|
|
|
163
163
|
"Christian Falch" => "christian.falch@gmail.com",
|
|
164
164
|
"William Candillon" => "wcandillon@gmail.com"
|
|
165
165
|
}
|
|
166
|
-
s.platforms = { :ios => "
|
|
166
|
+
s.platforms = { :ios => "15.1", :osx => "11" }
|
|
167
167
|
s.source = { :git => "https://github.com/wcandillon/react-native-skia.git", :tag => "#{s.version}" }
|
|
168
168
|
|
|
169
169
|
s.requires_arc = true
|
|
@@ -115,7 +115,7 @@ export const usePathInterpolation = (
|
|
|
115
115
|
// For example, throw an error or return early
|
|
116
116
|
throw new Error(
|
|
117
117
|
`Not all paths in the output range are interpolable.
|
|
118
|
-
See: https://
|
|
118
|
+
See: https://wcandillon.github.io/react-native-skia/docs/animations/hooks#usepathinterpolation`
|
|
119
119
|
);
|
|
120
120
|
}
|
|
121
121
|
return useInterpolator(
|
package/src/renderer/Canvas.tsx
CHANGED
|
@@ -99,7 +99,7 @@ const useCanvasRoot = ({
|
|
|
99
99
|
}: Pick<CanvasProps, "children" | "onSize" | "ref" | "onLayout">) => {
|
|
100
100
|
if (onLayout && Platform.OS !== "web") {
|
|
101
101
|
console.error(
|
|
102
|
-
"<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://
|
|
102
|
+
"<Canvas onLayout={onLayout} /> is not supported on the new architecture, to fix the issue, see: https://wcandillon.github.io/react-native-skia/docs/canvas/overview/#canvas-size"
|
|
103
103
|
);
|
|
104
104
|
}
|
|
105
105
|
const viewRef = useCanvasRefPriv(null);
|