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 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
- Checkout the full documentation [here](https://shopify.github.io/react-native-skia).
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
- Documentation on the library development is available [here](https://github.com/Shopify/react-native-skia#library-development).
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
- // WebGPU canvas values are sRGB-encoded regardless of the texture format
12
- // (GPUCanvasConfiguration.colorSpace defaults to "srgb"), so the same shader
13
- // output must display identically on bgra8unorm and rgba16float surfaces.
14
- // Tagging the float layer as (gamma-encoded) extended sRGB matches the
15
- // browser behavior: identical colors, with the extra precision of float16.
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(metalLayer,
24
- format == wgpu::TextureFormat::RGBA16Float, false);
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((__bridge void *)_layer,
98
- w, h, _highBitDepth);
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
  }
@@ -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() {
@@ -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, SkColorSpace::MakeSRGB(), &surfaceProps);
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), _width(width), _height(height) {
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, colorSpace, &surfaceProps);
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
- // Float formats need the layer tagged as (gamma-encoded) extended sRGB so
118
- // the sRGB-encoded values display identically to the 8-bit path.
119
- applyCAMetalLayerColorSpace(_nativeSurface, _format);
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 apple/MetalLayerColorSpace.mm.
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 and the
28
- * format of a window (or offscreen) surface. A deferred canvas is recorded
29
- * against this description, so it can be created before the surface itself
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 texture of its own
84
- size first (see RNSkView::present).
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
- _surface(context->makeOffscreenSurface(width, height)) {}
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
- SkImageInfo::Make(target.width, target.height, target.colorType,
158
- kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
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 surface will be
275
- created with, following the same rules (see DawnWindowContext and
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;
@@ -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
- } else {
221
- renderLastFrame(provider);
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 provider->makeSnapshot(bounds);
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
- Replays the frame on screen, or the one about to be, onto another
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
- if (recording == nullptr) {
318
- return false;
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 onto it, as one
339
- // batch; one of another size goes through a texture of its own size.
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 (presentResized(provider, recording)) {
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 presentResized(const std::shared_ptr<RNSkCanvasProvider> &provider,
391
- const std::shared_ptr<RNSkGraphiteRecording> &recording) {
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://shopify.github.io/react-native-skia/docs/animations/hooks#usepathinterpolation`);
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://shopify.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":[]}
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://shopify.github.io/react-native-skia/docs/canvas/overview/#getting-the-canvas-size");
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":";;;;;;AACA,IAAAA,MAAA,GAAAC,uBAAA,CAAAC,OAAA;AAkBA,IAAAC,gBAAA,GAAAC,sBAAA,CAAAF,OAAA;AACA,IAAAG,iBAAA,GAAAH,OAAA;AACA,IAAAI,QAAA,GAAAJ,OAAA;AAEA,IAAAK,wBAAA,GAAAH,sBAAA,CAAAF,OAAA;AAEA,IAAAM,WAAA,GAAAN,OAAA;AACA,IAAAO,KAAA,GAAAP,OAAA;AACA,IAAAQ,SAAA,GAAAR,OAAA;AACA,IAAAS,SAAA,GAAAT,OAAA;AAA+C,SAAAE,uBAAAQ,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAAA,SAAAX,wBAAAW,CAAA,EAAAG,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAf,uBAAA,YAAAA,CAAAW,CAAA,EAAAG,CAAA,SAAAA,CAAA,IAAAH,CAAA,IAAAA,CAAA,CAAAC,UAAA,SAAAD,CAAA,MAAAO,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAR,OAAA,EAAAF,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAS,CAAA,MAAAF,CAAA,GAAAJ,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAE,CAAA,CAAAI,GAAA,CAAAX,CAAA,UAAAO,CAAA,CAAAK,GAAA,CAAAZ,CAAA,GAAAO,CAAA,CAAAM,GAAA,CAAAb,CAAA,EAAAS,CAAA,gBAAAN,CAAA,IAAAH,CAAA,gBAAAG,CAAA,OAAAW,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAG,CAAA,OAAAK,CAAA,IAAAD,CAAA,GAAAS,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAG,CAAA,OAAAK,CAAA,CAAAI,GAAA,IAAAJ,CAAA,CAAAK,GAAA,IAAAN,CAAA,CAAAE,CAAA,EAAAN,CAAA,EAAAK,CAAA,IAAAC,CAAA,CAAAN,CAAA,IAAAH,CAAA,CAAAG,CAAA,WAAAM,CAAA,KAAAT,CAAA,EAAAG,CAAA;AAAA,SAAAgB,SAAA,WAAAA,QAAA,GAAAH,MAAA,CAAAI,MAAA,GAAAJ,MAAA,CAAAI,MAAA,CAAAC,IAAA,eAAAf,CAAA,aAAAN,CAAA,MAAAA,CAAA,GAAAsB,SAAA,CAAAC,MAAA,EAAAvB,CAAA,UAAAG,CAAA,GAAAmB,SAAA,CAAAtB,CAAA,YAAAK,CAAA,IAAAF,CAAA,OAAAW,cAAA,CAAAC,IAAA,CAAAZ,CAAA,EAAAE,CAAA,MAAAC,CAAA,CAAAD,CAAA,IAAAF,CAAA,CAAAE,CAAA,aAAAC,CAAA,KAAAa,QAAA,CAAAK,KAAA,OAAAF,SAAA;AAWxC,MAAMG,YAAY,GAAGA,CAAA,KAAM,IAAAC,aAAM,EAAY,IAAI,CAAC;AAACC,OAAA,CAAAF,YAAA,GAAAA,YAAA;AAE1D,MAAMG,kBAAkB,GAAG,CAACC,0BAAgB,GAAG,MAAM,CAAC,CAAC,GAAGC,wBAAG,CAACC,gBAAgB;AAC9E,MAAMC,OAAO,GAAG,CAACH,0BAAgB,GAAG,IAAI,GAAGC,wBAAG,CAACE,OAAO;AAEtD,MAAMC,gBAAqC,GAAG,CAACJ,0BAAgB,GAC3DH,aAAM,GACNI,wBAAG,CAACI,cAAc;AAEf,MAAMC,aAAa,GAAIC,OAAqC,IAAK;EACtE,MAAMC,MAAM,GAAGZ,YAAY,CAAC,CAAC;EAC7B,MAAMa,GAAG,GAAGF,OAAO,aAAPA,OAAO,cAAPA,OAAO,GAAIC,MAAM;EAC7B,MAAM,CAACE,IAAI,EAAEC,OAAO,CAAC,GAAG,IAAAC,eAAQ,EAAS;IAAEC,KAAK,EAAE,CAAC;IAAEC,MAAM,EAAE;EAAE,CAAC,CAAC;EACjE,IAAAC,sBAAe,EAAC,MAAM;IACpB,IAAIN,GAAG,CAACO,OAAO,EAAE;MACfP,GAAG,CAACO,OAAO,CAACb,OAAO,CAAC,CAACc,EAAE,EAAEC,EAAE,EAAEL,KAAK,EAAEC,MAAM,KAAK;QAC7CH,OAAO,CAAC;UAAEE,KAAK;UAAEC;QAAO,CAAC,CAAC;MAC5B,CAAC,CAAC;IACJ;IACA;EACF,CAAC,EAAE,EAAE,CAAC;EACN,OAAO;IAAEL,GAAG;IAAEC;EAAK,CAAC;AACtB,CAAC;AAACZ,OAAA,CAAAQ,aAAA,GAAAA,aAAA;AA4BF;AACA;AACA;AACA;AACA,MAAMa,aAAa,GAAGA,CAAC;EACrBC,QAAQ;EACRC,MAAM;EACNZ,GAAG;EACHa;AAC6D,CAAC,KAAK;EACnE,IAAIA,QAAQ,IAAIC,kBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;IACrCC,OAAO,CAACC,KAAK,CACX,2LACF,CAAC;EACH;EACA,MAAMC,OAAO,GAAGvB,gBAAgB,CAAC,IAAI,CAAC;EACtC;EACA,MAAMwB,QAAQ,GAAG,IAAAC,cAAO,EAAC,MAAM;IAC7B,OAAOC,kCAAgB,CAACd,OAAO,EAAE;EACnC,CAAC,EAAE,EAAE,CAAC;;EAEN;EACA,MAAMe,IAAI,GAAG,IAAAF,cAAO,EAAC,MAAM,IAAIG,sBAAU,CAACC,UAAI,EAAEL,QAAQ,CAAC,EAAE,CAACA,QAAQ,CAAC,CAAC;EAEtE7B,kBAAkB,CAAC,MAAM;IACvB,SAAS;;IACT,IAAIsB,MAAM,IAAIlB,OAAO,EAAE;MAAA,IAAA+B,gBAAA;MACrB,MAAMC,MAAM;MACV;MACAZ,kBAAQ,CAACC,EAAE,KAAK,KAAK;MACjB;MACA;MACA,CAAAU,gBAAA,GAAAP,OAAO,CAACX,OAAO,cAAAkB,gBAAA,eAAfA,gBAAA,CAAiBE,SAAS;MACxB;MACA;MACAjC,OAAO,CAACwB,OAAO,CAACX,OAAO,CAACoB,SAAS,CAAC,GAClC;QAAEvB,KAAK,EAAE,CAAC;QAAEC,MAAM,EAAE;MAAE,CAAC;MACzB;MACAX,OAAO,CAACwB,OAAc,CAAC;MAC7B,IAAIQ,MAAM,EAAE;QACV,MAAM;UAAEtB,KAAK;UAAEC;QAAO,CAAC,GAAGqB,MAAM;QAChC,IAAId,MAAM,CAACgB,KAAK,CAACxB,KAAK,KAAKA,KAAK,IAAIQ,MAAM,CAACgB,KAAK,CAACvB,MAAM,KAAKA,MAAM,EAAE;UAClEO,MAAM,CAACgB,KAAK,GAAG;YAAExB,KAAK;YAAEC;UAAO,CAAC;QAClC;MACF;IACF;EACF,CAAC,EAAE,CAAC,CAACO,MAAM,CAAC;;EAEZ;EACA,IAAAN,sBAAe,EAAC,MAAM;IACpBgB,IAAI,CAACO,MAAM,CAAClB,QAAQ,CAAC;EACvB,CAAC,EAAE,CAACA,QAAQ,EAAEW,IAAI,EAAEH,QAAQ,CAAC,CAAC;EAE9B,IAAAW,gBAAS,EAAC,MAAM;IACd,OAAO,MAAM;MACXR,IAAI,CAACS,OAAO,CAAC,CAAC;IAChB,CAAC;EACH,CAAC,EAAE,CAACT,IAAI,CAAC,CAAC;;EAEV;EACA,IAAAU,0BAAmB,EACjBhC,GAAG,EACH,OACG;IACCiC,iBAAiB,EAAGC,IAAa,IAAK;MACpC,OAAOC,WAAW,CAACF,iBAAiB,CAACd,QAAQ,EAAEe,IAAI,CAAC;IACtD,CAAC;IACDE,sBAAsB,EAAGF,IAAa,IAAK;MACzC,OAAOC,WAAW,CAACC,sBAAsB,CAACjB,QAAQ,EAAEe,IAAI,CAAC;IAC3D,CAAC;IACDG,MAAM,EAAEA,CAAA,KAAM;MACZF,WAAW,CAACG,aAAa,CAACnB,QAAQ,CAAC;IACrC,CAAC;IACDoB,WAAW,EAAEA,CAAA,KAAM;MACjB,OAAOpB,QAAQ;IACjB,CAAC;IACDzB,OAAO,EAAG8C,QAAQ,IAAK;MAAA,IAAAC,iBAAA;MACrB,CAAAA,iBAAA,GAAAvB,OAAO,CAACX,OAAO,cAAAkC,iBAAA,eAAfA,iBAAA,CAAiB/C,OAAO,CAAC8C,QAAQ,CAAC;IACpC,CAAC;IACDE,eAAe,EAAGF,QAAQ,IAAK;MAAA,IAAAG,iBAAA;MAC7B,CAAAA,iBAAA,GAAAzB,OAAO,CAACX,OAAO,cAAAoC,iBAAA,eAAfA,iBAAA,CAAiBD,eAAe,CAACF,QAAQ,CAAC;IAC5C;EACF,CAAC,CACL,CAAC;EACD,OAAO;IAAErB,QAAQ;IAAED;EAAQ,CAAC;AAC9B,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM0B,MAAM,GAAGA,CAAC;EACrBC,MAAM;EACNlC,QAAQ;EACRC,MAAM;EACNkC,YAAY,GAAG,KAAK;EACpBC,OAAO;EACP/C,GAAG;EACHa,QAAQ;EACR,GAAGmC;AACQ,CAAC,KAAK;EACjB,MAAM;IAAE7B,QAAQ;IAAED;EAAQ,CAAC,GAAGR,aAAa,CAAC;IAC1CC,QAAQ;IACRC,MAAM;IACNZ,GAAG;IACHa;EACF,CAAC,CAAC;EAEF,MAAMoC,WAAW,GAAG,IAAAC,kBAAW,EAC5BxF,CAAoB,IAAK;IACxB,IAAImD,QAAQ,EAAE;MACZA,QAAQ,CAACnD,CAAC,CAAC;IACb;IACA,IAAIoD,kBAAQ,CAACC,EAAE,KAAK,KAAK,IAAIH,MAAM,EAAE;MACnC,MAAM;QAAER,KAAK;QAAEC;MAAO,CAAC,GAAG3C,CAAC,CAACyF,WAAW,CAACC,MAAM;MAC9CxC,MAAM,CAACgB,KAAK,GAAG;QAAExB,KAAK;QAAEC;MAAO,CAAC;IAClC;EACF,CAAC,EACD,CAACQ,QAAQ,EAAED,MAAM,CACnB,CAAC;EACD,oBACE9D,MAAA,CAAAc,OAAA,CAAAyF,aAAA,CAAChG,wBAAA,CAAAO,OAAuB,EAAAiB,QAAA;IACtBmB,GAAG,EAAEkB,OAAQ;IACboC,WAAW,EAAE,KAAM;IACnBC,QAAQ,EAAE,GAAGpC,QAAQ,EAAG;IACxB0B,MAAM,EAAEA,MAAO;IACfC,YAAY,EAAEA;EAAa,GACvB,IAAAU,2BAAkB,EAACT,OAAO,CAAC;IAC/BlC,QAAQ,EACNC,kBAAQ,CAACC,EAAE,KAAK,KAAK,KAAKH,MAAM,IAAIC,QAAQ,CAAC,GAAGoC,WAAW,GAAGpC;EAC/D,GACGmC,SAAS,CACd,CAAC;AAEN,CAAC;AAAC3D,OAAA,CAAAuD,MAAA,GAAAA,MAAA","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://shopify.github.io/react-native-skia/docs/animations/hooks#usepathinterpolation`);
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://shopify.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":[]}
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://shopify.github.io/react-native-skia/docs/canvas/overview/#getting-the-canvas-size");
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.2",
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 => "14.0", :osx => "11" }
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://shopify.github.io/react-native-skia/docs/animations/hooks#usepathinterpolation`
118
+ See: https://wcandillon.github.io/react-native-skia/docs/animations/hooks#usepathinterpolation`
119
119
  );
120
120
  }
121
121
  return useInterpolator(
@@ -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://shopify.github.io/react-native-skia/docs/canvas/overview/#getting-the-canvas-size"
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);