@shopify/react-native-skia 0.1.180 → 0.1.181
Sign up to get free protection for your applications and to get access to all the features.
- package/android/build.gradle +6 -1
- package/cpp/jsi/RuntimeAwareCache.cpp +0 -2
- package/cpp/rnskia/RNSkDomView.cpp +2 -2
- package/cpp/rnskia/RNSkPlatformContext.h +2 -2
- package/cpp/rnskia/dom/base/JsiDependencyManager.h +10 -6
- package/cpp/rnskia/dom/base/JsiDomNode.h +133 -78
- package/cpp/rnskia/dom/base/JsiDomRenderNode.h +8 -8
- package/cpp/rnskia/dom/base/NodeProp.h +5 -5
- package/cpp/rnskia/dom/base/NodePropsContainer.h +7 -1
- package/cpp/rnskia/dom/props/ClipProp.h +13 -20
- package/cpp/rnskia/dom/props/PathProp.h +16 -14
- package/cpp/rnskia/dom/props/PointProp.h +1 -1
- package/cpp/rnskia/dom/props/RRectProp.h +39 -61
- package/cpp/rnskia/dom/props/RectProp.h +27 -25
- package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +0 -2
- package/lib/commonjs/views/SkiaBaseWebView.js +5 -1
- package/lib/commonjs/views/SkiaBaseWebView.js.map +1 -1
- package/lib/module/views/SkiaBaseWebView.js +5 -1
- package/lib/module/views/SkiaBaseWebView.js.map +1 -1
- package/package.json +1 -1
- package/src/views/SkiaBaseWebView.tsx +5 -0
package/android/build.gradle
CHANGED
@@ -28,6 +28,11 @@ def safeExtGet(prop, fallback) {
|
|
28
28
|
|
29
29
|
apply plugin: 'com.android.library'
|
30
30
|
|
31
|
+
def reactNativeArchitectures() {
|
32
|
+
def value = project.getProperties().get("reactNativeArchitectures")
|
33
|
+
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
34
|
+
}
|
35
|
+
|
31
36
|
static def findNodeModules(baseDir) {
|
32
37
|
def basePath = baseDir.toPath().normalize()
|
33
38
|
// Node's module resolution algorithm searches up to the root directory,
|
@@ -119,7 +124,7 @@ android {
|
|
119
124
|
externalNativeBuild {
|
120
125
|
cmake {
|
121
126
|
cppFlags "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID"
|
122
|
-
abiFilters
|
127
|
+
abiFilters (*reactNativeArchitectures())
|
123
128
|
arguments '-DANDROID_STL=c++_shared',
|
124
129
|
"-DREACT_NATIVE_VERSION=${REACT_NATIVE_VERSION}",
|
125
130
|
"-DNODE_MODULES_DIR=${nodeModules}",
|
@@ -22,7 +22,7 @@ RNSkDomRenderer::RNSkDomRenderer(std::function<void()> requestRedraw,
|
|
22
22
|
|
23
23
|
RNSkDomRenderer::~RNSkDomRenderer() {
|
24
24
|
if (_root != nullptr) {
|
25
|
-
_root->dispose();
|
25
|
+
_root->dispose(true);
|
26
26
|
_root = nullptr;
|
27
27
|
}
|
28
28
|
}
|
@@ -63,7 +63,7 @@ void RNSkDomRenderer::renderImmediate(
|
|
63
63
|
void RNSkDomRenderer::setRoot(std::shared_ptr<JsiDomRenderNode> node) {
|
64
64
|
std::lock_guard<std::mutex> lock(_rootLock);
|
65
65
|
if (_root != nullptr) {
|
66
|
-
_root->dispose();
|
66
|
+
_root->dispose(true);
|
67
67
|
_root = nullptr;
|
68
68
|
}
|
69
69
|
_root = node;
|
@@ -112,8 +112,8 @@ public:
|
|
112
112
|
|
113
113
|
/**
|
114
114
|
* Creates an offscreen surface
|
115
|
-
* @param width
|
116
|
-
* @param height
|
115
|
+
* @param width width of the surface
|
116
|
+
* @param height height of the surface
|
117
117
|
* @return sk_sp<SkSurface>
|
118
118
|
*/
|
119
119
|
virtual sk_sp<SkSurface> makeOffscreenSurface(int width, int height) = 0;
|
@@ -23,8 +23,10 @@ class JsiDependencyManager
|
|
23
23
|
public std::enable_shared_from_this<JsiDependencyManager> {
|
24
24
|
public:
|
25
25
|
JsiDependencyManager(std::shared_ptr<RNSkPlatformContext> context,
|
26
|
-
jsi::
|
27
|
-
|
26
|
+
jsi::Runtime &runtime,
|
27
|
+
const jsi::Value ®isterValuesCallback)
|
28
|
+
: _registerValuesCallback(std::make_shared<jsi::Object>(
|
29
|
+
registerValuesCallback.asObject(runtime))),
|
28
30
|
JsiHostObject() {}
|
29
31
|
|
30
32
|
~JsiDependencyManager() { unsubscribeAll(); }
|
@@ -158,7 +160,7 @@ public:
|
|
158
160
|
}
|
159
161
|
|
160
162
|
// Call JS registerValues callback
|
161
|
-
auto func = _registerValuesCallback
|
163
|
+
auto func = _registerValuesCallback->asFunction(runtime);
|
162
164
|
_unregisterValues = std::make_shared<jsi::Object>(
|
163
165
|
func.call(runtime, array, 1).asObject(runtime));
|
164
166
|
|
@@ -187,6 +189,8 @@ public:
|
|
187
189
|
|
188
190
|
unsubscribeAll();
|
189
191
|
|
192
|
+
_registerValuesCallback = nullptr;
|
193
|
+
|
190
194
|
return jsi::Value::undefined();
|
191
195
|
}
|
192
196
|
|
@@ -203,8 +207,8 @@ public:
|
|
203
207
|
return JSI_HOST_FUNCTION_LAMBDA {
|
204
208
|
// Params: registerValues: (values: Array<SkiaValue<unknown>>) => () =>
|
205
209
|
// void
|
206
|
-
auto obj = std::make_shared<JsiDependencyManager>(
|
207
|
-
|
210
|
+
auto obj = std::make_shared<JsiDependencyManager>(context, runtime,
|
211
|
+
arguments[0]);
|
208
212
|
|
209
213
|
return jsi::Object::createFromHostObject(runtime, std::move(obj));
|
210
214
|
};
|
@@ -283,7 +287,7 @@ private:
|
|
283
287
|
return false;
|
284
288
|
}
|
285
289
|
|
286
|
-
jsi::Object _registerValuesCallback;
|
290
|
+
std::shared_ptr<jsi::Object> _registerValuesCallback;
|
287
291
|
std::shared_ptr<jsi::Object> _unregisterValues;
|
288
292
|
std::map<JsiDomNode *,
|
289
293
|
std::vector<std::pair<std::shared_ptr<RNSkReadonlyValue>,
|
@@ -49,7 +49,19 @@ public:
|
|
49
49
|
JsiDomNode(std::shared_ptr<RNSkPlatformContext> context, const char *type,
|
50
50
|
NodeClass nodeClass)
|
51
51
|
: _type(type), _context(context), _nodeClass(nodeClass),
|
52
|
-
_nodeId(NodeIdent++), JsiHostObject() {
|
52
|
+
_nodeId(NodeIdent++), JsiHostObject() {
|
53
|
+
#if SKIA_DOM_DEBUG
|
54
|
+
printDebugInfo("JsiDomNode." + std::string(_type) +
|
55
|
+
" CTOR - nodeId: " + std::to_string(_nodeId));
|
56
|
+
#endif
|
57
|
+
}
|
58
|
+
|
59
|
+
virtual ~JsiDomNode() {
|
60
|
+
#if SKIA_DOM_DEBUG
|
61
|
+
printDebugInfo("JsiDomNode." + std::string(_type) +
|
62
|
+
" DTOR - nodeId: " + std::to_string(_nodeId));
|
63
|
+
#endif
|
64
|
+
}
|
53
65
|
|
54
66
|
/**
|
55
67
|
Called when creating the node, resolves properties from the node constructor.
|
@@ -65,7 +77,7 @@ public:
|
|
65
77
|
JSI_HOST_FUNCTION(setProps) {
|
66
78
|
if (count == 1) {
|
67
79
|
// Initialize properties container
|
68
|
-
setProps(runtime,
|
80
|
+
setProps(runtime, arguments[0]);
|
69
81
|
} else {
|
70
82
|
setEmptyProps();
|
71
83
|
}
|
@@ -102,7 +114,7 @@ public:
|
|
102
114
|
tree. Use for cleaning up.
|
103
115
|
*/
|
104
116
|
JSI_HOST_FUNCTION(dispose) {
|
105
|
-
dispose();
|
117
|
+
dispose(false);
|
106
118
|
return jsi::Value::undefined();
|
107
119
|
}
|
108
120
|
|
@@ -247,36 +259,9 @@ public:
|
|
247
259
|
_propsContainer->markAsResolved();
|
248
260
|
}
|
249
261
|
|
250
|
-
// Now let's
|
262
|
+
// Now let's invalidate if needed
|
251
263
|
if (_isDisposing && !_isDisposed) {
|
252
|
-
|
253
|
-
|
254
|
-
this->setParent(nullptr);
|
255
|
-
|
256
|
-
// Callback signaling that we're done
|
257
|
-
if (_disposeCallback != nullptr) {
|
258
|
-
_disposeCallback();
|
259
|
-
_disposeCallback = nullptr;
|
260
|
-
}
|
261
|
-
|
262
|
-
// Clear props
|
263
|
-
if (_propsContainer != nullptr) {
|
264
|
-
_propsContainer->dispose();
|
265
|
-
}
|
266
|
-
|
267
|
-
// Remove children
|
268
|
-
std::vector<std::shared_ptr<JsiDomNode>> tmp;
|
269
|
-
{
|
270
|
-
std::lock_guard<std::mutex> lock(_childrenLock);
|
271
|
-
tmp.reserve(_children.size());
|
272
|
-
for (auto &child : _children) {
|
273
|
-
tmp.push_back(child);
|
274
|
-
}
|
275
|
-
_children.clear();
|
276
|
-
}
|
277
|
-
for (auto &child : tmp) {
|
278
|
-
child->dispose();
|
279
|
-
}
|
264
|
+
invalidate();
|
280
265
|
}
|
281
266
|
|
282
267
|
// Resolve children
|
@@ -292,6 +277,22 @@ public:
|
|
292
277
|
// Empty implementation
|
293
278
|
}
|
294
279
|
|
280
|
+
/**
|
281
|
+
Called when a node has been removed from the dom tree and needs to be cleaned
|
282
|
+
up. If the invalidate parameter is set, we will invalidate the node directly.
|
283
|
+
Calling dispose from the JS dispose function calls this with invalidate set
|
284
|
+
to false, while the dom render view calls this with true.
|
285
|
+
*/
|
286
|
+
virtual void dispose(bool immediate) {
|
287
|
+
if (_isDisposing) {
|
288
|
+
return;
|
289
|
+
}
|
290
|
+
_isDisposing = true;
|
291
|
+
if (immediate) {
|
292
|
+
invalidate();
|
293
|
+
}
|
294
|
+
}
|
295
|
+
|
295
296
|
protected:
|
296
297
|
/**
|
297
298
|
Adds an operation that will be executed when the render cycle is finished.
|
@@ -319,24 +320,17 @@ protected:
|
|
319
320
|
|
320
321
|
/**
|
321
322
|
Native implementation of the set properties method. This is called from the
|
322
|
-
reconciler when properties are set due to changes in React.
|
323
|
-
always call the onPropsSet method as a signal that things have changed.
|
323
|
+
reconciler when properties are set due to changes in React.
|
324
324
|
*/
|
325
|
-
void setProps(jsi::Runtime &runtime, jsi::
|
325
|
+
void setProps(jsi::Runtime &runtime, const jsi::Value &maybeProps) {
|
326
326
|
#if SKIA_DOM_DEBUG
|
327
327
|
printDebugInfo("JS:setProps(nodeId: " + std::to_string(_nodeId) + ")");
|
328
328
|
#endif
|
329
|
-
|
329
|
+
// Initialize properties container
|
330
|
+
ensurePropertyContainer();
|
330
331
|
|
331
|
-
// Initialize properties container
|
332
|
-
_propsContainer = std::make_shared<NodePropsContainer>(
|
333
|
-
getType(), [=](BaseNodeProp *p) { onPropertyChanged(p); });
|
334
|
-
|
335
|
-
// Ask sub classes to define their properties
|
336
|
-
defineProperties(_propsContainer.get());
|
337
|
-
}
|
338
332
|
// Update properties container
|
339
|
-
_propsContainer->setProps(runtime,
|
333
|
+
_propsContainer->setProps(runtime, maybeProps);
|
340
334
|
|
341
335
|
// Invalidate context
|
342
336
|
invalidateContext();
|
@@ -349,15 +343,8 @@ protected:
|
|
349
343
|
#if SKIA_DOM_DEBUG
|
350
344
|
printDebugInfo("JS:setEmptyProps(nodeId: " + std::to_string(_nodeId) + ")");
|
351
345
|
#endif
|
352
|
-
|
353
|
-
|
354
|
-
// Initialize properties container
|
355
|
-
_propsContainer = std::make_shared<NodePropsContainer>(
|
356
|
-
getType(), [=](BaseNodeProp *p) { onPropertyChanged(p); });
|
357
|
-
|
358
|
-
// Ask sub classes to define their properties
|
359
|
-
defineProperties(_propsContainer.get());
|
360
|
-
}
|
346
|
+
// Initialize properties container
|
347
|
+
ensurePropertyContainer();
|
361
348
|
}
|
362
349
|
|
363
350
|
/**
|
@@ -381,9 +368,12 @@ protected:
|
|
381
368
|
printDebugInfo("JS:addChild(childId: " + std::to_string(child->_nodeId) +
|
382
369
|
")");
|
383
370
|
#endif
|
384
|
-
enqueAsynOperation([child,
|
385
|
-
|
386
|
-
|
371
|
+
enqueAsynOperation([child, weakSelf = weak_from_this()]() {
|
372
|
+
auto self = weakSelf.lock();
|
373
|
+
if (self) {
|
374
|
+
self->_children.push_back(child);
|
375
|
+
child->setParent(self.get());
|
376
|
+
}
|
387
377
|
});
|
388
378
|
}
|
389
379
|
|
@@ -398,10 +388,14 @@ protected:
|
|
398
388
|
"JS:insertChildBefore(childId: " + std::to_string(child->_nodeId) +
|
399
389
|
", beforeId: " + std::to_string(before->_nodeId) + ")");
|
400
390
|
#endif
|
401
|
-
enqueAsynOperation([child, before,
|
402
|
-
auto
|
403
|
-
|
404
|
-
|
391
|
+
enqueAsynOperation([child, before, weakSelf = weak_from_this()]() {
|
392
|
+
auto self = weakSelf.lock();
|
393
|
+
if (self) {
|
394
|
+
auto position =
|
395
|
+
std::find(self->_children.begin(), self->_children.end(), before);
|
396
|
+
self->_children.insert(position, child);
|
397
|
+
child->setParent(self.get());
|
398
|
+
}
|
405
399
|
});
|
406
400
|
}
|
407
401
|
|
@@ -414,27 +408,25 @@ protected:
|
|
414
408
|
printDebugInfo("JS:removeChild(childId: " + std::to_string(child->_nodeId) +
|
415
409
|
")");
|
416
410
|
#endif
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
411
|
+
auto removeChild = [child,
|
412
|
+
weakSelf = weak_from_this()](bool immediate = false) {
|
413
|
+
auto self = weakSelf.lock();
|
414
|
+
if (self) {
|
415
|
+
// Delete child itself
|
416
|
+
self->_children.erase(
|
417
|
+
std::remove_if(self->_children.begin(), self->_children.end(),
|
418
|
+
[child](const auto &node) { return node == child; }),
|
419
|
+
self->_children.end());
|
420
|
+
|
421
|
+
child->dispose(immediate);
|
422
|
+
}
|
423
|
+
};
|
427
424
|
|
428
|
-
/**
|
429
|
-
Called when a node has been removed from the dom tree and needs to be cleaned
|
430
|
-
up.
|
431
|
-
*/
|
432
|
-
virtual void dispose() {
|
433
425
|
if (_isDisposing) {
|
434
|
-
|
426
|
+
removeChild(false);
|
427
|
+
} else {
|
428
|
+
enqueAsynOperation(removeChild);
|
435
429
|
}
|
436
|
-
|
437
|
-
_isDisposing = true;
|
438
430
|
}
|
439
431
|
|
440
432
|
#if SKIA_DOM_DEBUG
|
@@ -477,6 +469,69 @@ protected:
|
|
477
469
|
}
|
478
470
|
|
479
471
|
private:
|
472
|
+
/**
|
473
|
+
Invalidates the node - meaning removing and clearing children and properties
|
474
|
+
**/
|
475
|
+
void invalidate() {
|
476
|
+
if (_isDisposing && !_isDisposed) {
|
477
|
+
#if SKIA_DOM_DEBUG
|
478
|
+
printDebugInfo("JsiDomNode::invalidate: nodeid: " +
|
479
|
+
std::to_string(_nodeId));
|
480
|
+
#endif
|
481
|
+
|
482
|
+
_isDisposed = true;
|
483
|
+
|
484
|
+
// Clear parent
|
485
|
+
this->setParent(nullptr);
|
486
|
+
|
487
|
+
// Clear any async operations
|
488
|
+
_queuedNodeOps.clear();
|
489
|
+
|
490
|
+
// Callback signaling that we're done
|
491
|
+
if (_disposeCallback != nullptr) {
|
492
|
+
_disposeCallback();
|
493
|
+
_disposeCallback = nullptr;
|
494
|
+
}
|
495
|
+
|
496
|
+
// Clear props
|
497
|
+
if (_propsContainer != nullptr) {
|
498
|
+
_propsContainer->dispose();
|
499
|
+
}
|
500
|
+
|
501
|
+
// Remove children
|
502
|
+
std::vector<std::shared_ptr<JsiDomNode>> tmp;
|
503
|
+
{
|
504
|
+
std::lock_guard<std::mutex> lock(_childrenLock);
|
505
|
+
tmp.reserve(_children.size());
|
506
|
+
for (auto &child : _children) {
|
507
|
+
tmp.push_back(child);
|
508
|
+
}
|
509
|
+
_children.clear();
|
510
|
+
}
|
511
|
+
for (auto &child : tmp) {
|
512
|
+
child->dispose(true);
|
513
|
+
}
|
514
|
+
}
|
515
|
+
}
|
516
|
+
|
517
|
+
/**
|
518
|
+
Creates and sets up the property container
|
519
|
+
*/
|
520
|
+
void ensurePropertyContainer() {
|
521
|
+
if (_propsContainer == nullptr) {
|
522
|
+
_propsContainer = std::make_shared<NodePropsContainer>(
|
523
|
+
getType(), [weakSelf = weak_from_this()](BaseNodeProp *p) {
|
524
|
+
auto self = weakSelf.lock();
|
525
|
+
if (self) {
|
526
|
+
self->onPropertyChanged(p);
|
527
|
+
}
|
528
|
+
});
|
529
|
+
|
530
|
+
// Ask sub classes to define their properties
|
531
|
+
defineProperties(_propsContainer.get());
|
532
|
+
}
|
533
|
+
}
|
534
|
+
|
480
535
|
const char *_type;
|
481
536
|
std::shared_ptr<RNSkPlatformContext> _context;
|
482
537
|
|
@@ -132,19 +132,19 @@ public:
|
|
132
132
|
*/
|
133
133
|
void resetPendingChanges() override { JsiDomNode::resetPendingChanges(); }
|
134
134
|
|
135
|
-
/**
|
136
|
-
Signal from the JS side that the node is removed from the dom.
|
137
|
-
*/
|
138
|
-
void dispose() override { JsiDomNode::dispose(); }
|
139
|
-
|
140
135
|
protected:
|
141
136
|
/**
|
142
137
|
Invalidates and marks then context as changed.
|
143
138
|
*/
|
144
139
|
void invalidateContext() override {
|
145
|
-
enqueAsynOperation([=]() {
|
146
|
-
|
147
|
-
|
140
|
+
enqueAsynOperation([weakSelf = weak_from_this()]() {
|
141
|
+
auto self = weakSelf.lock();
|
142
|
+
if (self) {
|
143
|
+
std::static_pointer_cast<JsiDomRenderNode>(self)->_paintCache.parent =
|
144
|
+
nullptr;
|
145
|
+
std::static_pointer_cast<JsiDomRenderNode>(self)->_paintCache.child =
|
146
|
+
nullptr;
|
147
|
+
}
|
148
148
|
});
|
149
149
|
}
|
150
150
|
|
@@ -33,7 +33,7 @@ public:
|
|
33
33
|
// readValueFromJS Function (which comes from the reconciler
|
34
34
|
// setting a new property value on the property
|
35
35
|
if (_value == nullptr) {
|
36
|
-
_value = std::
|
36
|
+
_value = std::make_unique<JsiValue>(runtime, read(runtime, _name, this));
|
37
37
|
_isChanged = true;
|
38
38
|
_hasNewValue = false;
|
39
39
|
} else {
|
@@ -41,7 +41,7 @@ public:
|
|
41
41
|
std::lock_guard<std::mutex> lock(_swapMutex);
|
42
42
|
if (_buffer == nullptr) {
|
43
43
|
_buffer =
|
44
|
-
std::
|
44
|
+
std::make_unique<JsiValue>(runtime, read(runtime, _name, this));
|
45
45
|
} else {
|
46
46
|
_buffer->setCurrent(runtime, read(runtime, _name, this));
|
47
47
|
}
|
@@ -60,7 +60,7 @@ public:
|
|
60
60
|
// and we don't want to rip out the underlying value object.
|
61
61
|
std::lock_guard<std::mutex> lock(_swapMutex);
|
62
62
|
if (_buffer == nullptr) {
|
63
|
-
_buffer = std::
|
63
|
+
_buffer = std::make_unique<JsiValue>(runtime, value);
|
64
64
|
} else {
|
65
65
|
_buffer->setCurrent(runtime, value);
|
66
66
|
}
|
@@ -129,8 +129,8 @@ private:
|
|
129
129
|
|
130
130
|
std::function<void(BaseNodeProp *)> _onChange;
|
131
131
|
|
132
|
-
std::
|
133
|
-
std::
|
132
|
+
std::unique_ptr<JsiValue> _value;
|
133
|
+
std::unique_ptr<JsiValue> _buffer;
|
134
134
|
std::atomic<bool> _isChanged = {false};
|
135
135
|
std::atomic<bool> _hasNewValue = {false};
|
136
136
|
std::mutex _swapMutex;
|
@@ -82,10 +82,16 @@ public:
|
|
82
82
|
/**
|
83
83
|
Called when the React / JS side sets properties on a node
|
84
84
|
*/
|
85
|
-
void setProps(jsi::Runtime &runtime, jsi::
|
85
|
+
void setProps(jsi::Runtime &runtime, const jsi::Value &maybePropsObject) {
|
86
86
|
// Clear property mapping
|
87
87
|
_mappedProperties.clear();
|
88
88
|
|
89
|
+
if (!maybePropsObject.isObject()) {
|
90
|
+
throw jsi::JSError(runtime, "Expected property object.");
|
91
|
+
}
|
92
|
+
|
93
|
+
auto props = maybePropsObject.asObject(runtime);
|
94
|
+
|
89
95
|
// Use specialized reader function to be able to intercept calls that
|
90
96
|
// reads specific named values from the js property object.
|
91
97
|
auto read = [&](jsi::Runtime &runtime, PropId name, NodeProp *prop) {
|
@@ -22,43 +22,36 @@ public:
|
|
22
22
|
explicit ClipProp(PropId name,
|
23
23
|
const std::function<void(BaseNodeProp *)> &onChange)
|
24
24
|
: BaseDerivedProp(onChange) {
|
25
|
-
|
26
|
-
_rectProp = defineProperty<RectProp>(name);
|
27
|
-
_rrectProp = defineProperty<RRectProp>(name);
|
25
|
+
_clipProp = defineProperty<NodeProp>(name);
|
28
26
|
}
|
29
27
|
|
30
28
|
void updateDerivedValue() override {
|
31
|
-
if (
|
32
|
-
|
33
|
-
|
34
|
-
_path = _pathProp->getDerivedValue();
|
35
|
-
} else if (_rrectProp->isSet()) {
|
36
|
-
_rect = nullptr;
|
37
|
-
_rrect = _rrectProp->getDerivedValue();
|
38
|
-
_path = nullptr;
|
39
|
-
} else if (_rectProp->isSet()) {
|
40
|
-
_rect = _rectProp->getDerivedValue();
|
29
|
+
if (_clipProp->isSet()) {
|
30
|
+
auto value = _clipProp->value();
|
31
|
+
_rect = RectProp::processRect(value);
|
41
32
|
_rrect = nullptr;
|
42
33
|
_path = nullptr;
|
34
|
+
if (!_rect) {
|
35
|
+
_path = PathProp::processPath(value);
|
36
|
+
if (!_path) {
|
37
|
+
_rrect = RRectProp::processRRect(value);
|
38
|
+
}
|
39
|
+
}
|
43
40
|
}
|
44
41
|
}
|
45
42
|
|
46
|
-
bool isSet() override {
|
47
|
-
return _pathProp->isSet() || _rectProp->isSet() || _rrectProp->isSet();
|
48
|
-
}
|
43
|
+
bool isSet() override { return _clipProp->isSet(); }
|
49
44
|
|
50
45
|
const SkPath *getPath() { return _path.get(); }
|
51
46
|
const SkRect *getRect() { return _rect.get(); }
|
52
47
|
const SkRRect *getRRect() { return _rrect.get(); }
|
53
48
|
|
54
49
|
private:
|
55
|
-
|
56
|
-
RectProp *_rectProp;
|
57
|
-
RRectProp *_rrectProp;
|
50
|
+
NodeProp *_clipProp;
|
58
51
|
|
59
52
|
std::shared_ptr<const SkPath> _path;
|
60
53
|
std::shared_ptr<const SkRect> _rect;
|
61
54
|
std::shared_ptr<const SkRRect> _rrect;
|
62
55
|
};
|
63
56
|
|
64
|
-
} // namespace RNSkia
|
57
|
+
} // namespace RNSkia
|
@@ -22,32 +22,34 @@ public:
|
|
22
22
|
_pathProp = defineProperty<NodeProp>(name);
|
23
23
|
}
|
24
24
|
|
25
|
-
|
26
|
-
if (
|
27
|
-
setDerivedValue(nullptr);
|
28
|
-
return;
|
29
|
-
}
|
30
|
-
|
31
|
-
if (_pathProp->value().getType() == PropType::HostObject) {
|
25
|
+
static std::shared_ptr<SkPath> processPath(const JsiValue &value) {
|
26
|
+
if (value.getType() == PropType::HostObject) {
|
32
27
|
// Try reading as Path
|
33
|
-
auto ptr = std::dynamic_pointer_cast<JsiSkPath>(
|
34
|
-
_pathProp->value().getAsHostObject());
|
28
|
+
auto ptr = std::dynamic_pointer_cast<JsiSkPath>(value.getAsHostObject());
|
35
29
|
if (ptr != nullptr) {
|
36
|
-
|
30
|
+
return ptr->getObject();
|
37
31
|
}
|
38
|
-
} else if (
|
32
|
+
} else if (value.getType() == PropType::String) {
|
39
33
|
// Read as string
|
40
|
-
auto pathString =
|
34
|
+
auto pathString = value.getAsString();
|
41
35
|
SkPath result;
|
42
36
|
|
43
37
|
if (SkParsePath::FromSVGString(pathString.c_str(), &result)) {
|
44
|
-
|
38
|
+
return std::make_shared<SkPath>(result);
|
45
39
|
} else {
|
46
40
|
throw std::runtime_error("Could not parse path from string.");
|
47
41
|
}
|
48
|
-
}
|
42
|
+
}
|
43
|
+
return nullptr;
|
44
|
+
}
|
45
|
+
|
46
|
+
void updateDerivedValue() override {
|
47
|
+
if (!_pathProp->isSet()) {
|
49
48
|
setDerivedValue(nullptr);
|
49
|
+
return;
|
50
50
|
}
|
51
|
+
auto value = _pathProp->value();
|
52
|
+
setDerivedValue(PathProp::processPath(value));
|
51
53
|
}
|
52
54
|
|
53
55
|
private:
|
@@ -29,7 +29,7 @@ public:
|
|
29
29
|
void updateDerivedValue() override {
|
30
30
|
if (_pointProp->isSet()) {
|
31
31
|
// Check for JsiSkRect and JsiSkPoint
|
32
|
-
setDerivedValue(
|
32
|
+
setDerivedValue(processValue(_pointProp->value()));
|
33
33
|
} else {
|
34
34
|
setDerivedValue(nullptr);
|
35
35
|
}
|
@@ -33,35 +33,33 @@ public:
|
|
33
33
|
_prop = defineProperty<NodeProp>(name);
|
34
34
|
}
|
35
35
|
|
36
|
-
|
37
|
-
if (
|
38
|
-
//
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
auto
|
57
|
-
auto
|
58
|
-
auto
|
59
|
-
auto
|
60
|
-
auto rx = _prop->value().getValue(PropNameRx);
|
61
|
-
auto ry = _prop->value().getValue(PropNameRy);
|
36
|
+
static std::shared_ptr<SkRRect> processRRect(const JsiValue &value) {
|
37
|
+
if (value.getType() == PropType::HostObject) {
|
38
|
+
// Try reading as rect
|
39
|
+
auto rectPtr =
|
40
|
+
std::dynamic_pointer_cast<JsiSkRRect>(value.getAsHostObject());
|
41
|
+
if (rectPtr != nullptr) {
|
42
|
+
auto rrect = rectPtr->getObject();
|
43
|
+
return std::make_shared<SkRRect>(
|
44
|
+
SkRRect::MakeRectXY(rrect->rect(), rrect->getSimpleRadii().x(),
|
45
|
+
rrect->getSimpleRadii().y()));
|
46
|
+
}
|
47
|
+
} else {
|
48
|
+
if (value.getType() == PropType::Object) {
|
49
|
+
if (value.hasValue(PropNameRect) && value.hasValue(PropNameRx) &&
|
50
|
+
value.hasValue(PropNameRy)) {
|
51
|
+
auto rect = value.getValue(PropNameRect);
|
52
|
+
if (rect.hasValue(PropNameX) && rect.hasValue(PropNameY) &&
|
53
|
+
rect.hasValue(PropNameWidth) && rect.hasValue(PropNameHeight)) {
|
54
|
+
auto x = rect.getValue(PropNameX);
|
55
|
+
auto y = rect.getValue(PropNameY);
|
56
|
+
auto width = rect.getValue(PropNameWidth);
|
57
|
+
auto height = rect.getValue(PropNameHeight);
|
58
|
+
auto rx = value.getValue(PropNameRx);
|
59
|
+
auto ry = value.getValue(PropNameRy);
|
62
60
|
|
63
61
|
// Update cache from js object value
|
64
|
-
|
62
|
+
return std::make_shared<SkRRect>(SkRRect::MakeRectXY(
|
65
63
|
SkRect::MakeXYWH(x.getAsNumber(), y.getAsNumber(),
|
66
64
|
width.getAsNumber(), height.getAsNumber()),
|
67
65
|
rx.getAsNumber(), ry.getAsNumber()));
|
@@ -69,6 +67,14 @@ public:
|
|
69
67
|
}
|
70
68
|
}
|
71
69
|
}
|
70
|
+
return nullptr;
|
71
|
+
}
|
72
|
+
|
73
|
+
void updateDerivedValue() override {
|
74
|
+
if (_prop->isSet()) {
|
75
|
+
auto value = _prop->value();
|
76
|
+
setDerivedValue(RRectProp::processRRect(value));
|
77
|
+
}
|
72
78
|
}
|
73
79
|
|
74
80
|
private:
|
@@ -150,40 +156,12 @@ public:
|
|
150
156
|
}
|
151
157
|
|
152
158
|
void updateDerivedValue() override {
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
if (rectPtr != nullptr) {
|
160
|
-
auto rect = rectPtr->getObject();
|
161
|
-
setDerivedValue(SkRRect::MakeRect(*rect));
|
162
|
-
// 2. box is SkRRect
|
163
|
-
} else if (rrectPtr != nullptr) {
|
164
|
-
setDerivedValue(rrectPtr->getObject());
|
165
|
-
}
|
166
|
-
} else if (_boxProp->value().getType() == PropType::Object) {
|
167
|
-
if (_boxProp->value().hasValue(PropNameRect)) {
|
168
|
-
// 3. box is { rect: { x, y, width, height }, rx, ry }
|
169
|
-
auto rectProp = _boxProp->value().getValue(PropNameRect);
|
170
|
-
auto x = rectProp.getValue(PropNameX).getAsNumber();
|
171
|
-
auto y = rectProp.getValue(PropNameY).getAsNumber();
|
172
|
-
auto width = rectProp.getValue(PropNameWidth).getAsNumber();
|
173
|
-
auto height = rectProp.getValue(PropNameHeight).getAsNumber();
|
174
|
-
auto rx = _boxProp->value().getValue(PropNameRx).getAsNumber();
|
175
|
-
auto ry = _boxProp->value().getValue(PropNameRy).getAsNumber();
|
176
|
-
setDerivedValue(
|
177
|
-
SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, width, height), rx, ry));
|
178
|
-
} else {
|
179
|
-
// 4. box is { x, y, width, height }
|
180
|
-
auto x = _boxProp->value().getValue(PropNameX).getAsNumber();
|
181
|
-
auto y = _boxProp->value().getValue(PropNameY).getAsNumber();
|
182
|
-
auto width = _boxProp->value().getValue(PropNameWidth).getAsNumber();
|
183
|
-
auto height = _boxProp->value().getValue(PropNameHeight).getAsNumber();
|
184
|
-
setDerivedValue(
|
185
|
-
SkRRect::MakeRect(SkRect::MakeXYWH(x, y, width, height)));
|
186
|
-
}
|
159
|
+
auto value = _boxProp->value();
|
160
|
+
auto rect = RectProp::processRect(value);
|
161
|
+
if (rect) {
|
162
|
+
setDerivedValue(SkRRect::MakeRect(*rect));
|
163
|
+
} else {
|
164
|
+
setDerivedValue(RRectProp::processRRect(value));
|
187
165
|
}
|
188
166
|
}
|
189
167
|
|
@@ -31,33 +31,35 @@ public:
|
|
31
31
|
_prop = defineProperty<NodeProp>(name);
|
32
32
|
}
|
33
33
|
|
34
|
+
static std::shared_ptr<SkRect> processRect(const JsiValue &value) {
|
35
|
+
if (value.getType() == PropType::HostObject) {
|
36
|
+
auto rectPtr =
|
37
|
+
std::dynamic_pointer_cast<JsiSkRect>(value.getAsHostObject());
|
38
|
+
if (rectPtr != nullptr) {
|
39
|
+
return std::make_shared<SkRect>(SkRect::MakeXYWH(
|
40
|
+
rectPtr->getObject()->x(), rectPtr->getObject()->y(),
|
41
|
+
rectPtr->getObject()->width(), rectPtr->getObject()->height()));
|
42
|
+
}
|
43
|
+
} else if (value.getType() == PropType::Object &&
|
44
|
+
value.hasValue(PropNameX) && value.hasValue(PropNameY) &&
|
45
|
+
value.hasValue(PropNameWidth) &&
|
46
|
+
value.hasValue(PropNameHeight)) {
|
47
|
+
// Save props for fast access
|
48
|
+
auto x = value.getValue(PropNameX);
|
49
|
+
auto y = value.getValue(PropNameY);
|
50
|
+
auto width = value.getValue(PropNameWidth);
|
51
|
+
auto height = value.getValue(PropNameHeight);
|
52
|
+
// Update cache from js object value
|
53
|
+
return std::make_shared<SkRect>(
|
54
|
+
SkRect::MakeXYWH(x.getAsNumber(), y.getAsNumber(),
|
55
|
+
width.getAsNumber(), height.getAsNumber()));
|
56
|
+
}
|
57
|
+
return nullptr;
|
58
|
+
}
|
59
|
+
|
34
60
|
void updateDerivedValue() override {
|
35
61
|
if (_prop->isSet()) {
|
36
|
-
|
37
|
-
if (_prop->value().getType() == PropType::HostObject) {
|
38
|
-
auto rectPtr = std::dynamic_pointer_cast<JsiSkRect>(
|
39
|
-
_prop->value().getAsHostObject());
|
40
|
-
if (rectPtr != nullptr) {
|
41
|
-
setDerivedValue(SkRect::MakeXYWH(
|
42
|
-
rectPtr->getObject()->x(), rectPtr->getObject()->y(),
|
43
|
-
rectPtr->getObject()->width(), rectPtr->getObject()->height()));
|
44
|
-
}
|
45
|
-
} else {
|
46
|
-
auto p = _prop->value();
|
47
|
-
if (p.hasValue(PropNameX) && p.hasValue(PropNameY) &&
|
48
|
-
p.hasValue(PropNameWidth) && p.hasValue(PropNameHeight)) {
|
49
|
-
// Save props for fast access
|
50
|
-
auto x = p.getValue(PropNameX);
|
51
|
-
auto y = p.getValue(PropNameY);
|
52
|
-
auto width = p.getValue(PropNameWidth);
|
53
|
-
auto height = p.getValue(PropNameHeight);
|
54
|
-
|
55
|
-
// Update cache from js object value
|
56
|
-
setDerivedValue(SkRect::MakeXYWH(x.getAsNumber(), y.getAsNumber(),
|
57
|
-
width.getAsNumber(),
|
58
|
-
height.getAsNumber()));
|
59
|
-
}
|
60
|
-
}
|
62
|
+
setDerivedValue(RectProp::processRect(_prop->value()));
|
61
63
|
}
|
62
64
|
}
|
63
65
|
|
@@ -4,7 +4,6 @@
|
|
4
4
|
#include <thread>
|
5
5
|
#include <utility>
|
6
6
|
|
7
|
-
#include <RNSkMeasureTime.h>
|
8
7
|
#include <SkiaMetalRenderer.h>
|
9
8
|
|
10
9
|
#pragma clang diagnostic push
|
@@ -20,7 +19,6 @@ void RNSkiOSPlatformContext::performStreamOperation(
|
|
20
19
|
const std::string &sourceUri,
|
21
20
|
const std::function<void(std::unique_ptr<SkStreamAsset>)> &op) {
|
22
21
|
|
23
|
-
RNSkMeasureTime("PlatformContext::performStreamOperation");
|
24
22
|
auto loader = [=]() {
|
25
23
|
NSURL *url = [[NSURL alloc]
|
26
24
|
initWithString:[NSString stringWithUTF8String:sourceUri.c_str()]];
|
@@ -103,8 +103,12 @@ class SkiaBaseWebView extends _react.default.Component {
|
|
103
103
|
}
|
104
104
|
|
105
105
|
componentWillUnmount() {
|
106
|
+
var _this$_canvasRef$curr, _this$_canvasRef$curr2, _this$_canvasRef$curr3;
|
107
|
+
|
106
108
|
this.unsubscribeAll();
|
107
|
-
cancelAnimationFrame(this.requestId);
|
109
|
+
cancelAnimationFrame(this.requestId); // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context
|
110
|
+
|
111
|
+
(_this$_canvasRef$curr = this._canvasRef.current) === null || _this$_canvasRef$curr === void 0 ? void 0 : (_this$_canvasRef$curr2 = _this$_canvasRef$curr.getContext("webgl2")) === null || _this$_canvasRef$curr2 === void 0 ? void 0 : (_this$_canvasRef$curr3 = _this$_canvasRef$curr2.getExtension("WEBGL_lose_context")) === null || _this$_canvasRef$curr3 === void 0 ? void 0 : _this$_canvasRef$curr3.loseContext();
|
108
112
|
}
|
109
113
|
/**
|
110
114
|
* Creates a snapshot from the canvas in the surface
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"names":["pd","PixelRatio","get","SkiaBaseWebView","React","Component","constructor","props","createRef","_mode","mode","unsubscribeAll","_unsubscriptions","forEach","u","onLayout","evt","CanvasKit","global","width","height","nativeEvent","layout","_canvasRef","current","canvas","surface","MakeWebGLCanvasSurface","Error","_surface","JsiSkSurface","_canvas","getCanvas","redraw","getSize","componentDidMount","tick","componentDidUpdate","componentWillUnmount","cancelAnimationFrame","requestId","makeImageSnapshot","rect","clear","TRANSPARENT","renderInCanvas","ref","flush","_redrawRequests","touches","_touches","Float32Array","of","save","scale","restore","requestAnimationFrame","bind","setDrawMode","registerValues","_values","v","push","addListener","handleTouchEvent","touchType","id","pointerId","x","clientX","currentTarget","getClientRects","left","y","clientY","top","force","pressure","type","timestamp","Date","now","createTouchHandler","render","debug","viewProps","display","flex","TouchType","Start","Active","End","Cancelled"],"sources":["SkiaBaseWebView.tsx"],"sourcesContent":["/* global HTMLCanvasElement */\nimport React from \"react\";\nimport type { PointerEvent } from \"react\";\nimport type { LayoutChangeEvent } from \"react-native\";\nimport { PixelRatio, View } from \"react-native\";\n\nimport type { SkRect, SkCanvas } from \"../skia/types\";\nimport type { SkiaValue } from \"../values\";\nimport { JsiSkSurface } from \"../skia/web/JsiSkSurface\";\n\nimport type { DrawMode, SkiaBaseViewProps, TouchInfo } from \"./types\";\nimport { TouchType } from \"./types\";\n\nconst pd = PixelRatio.get();\n\nexport abstract class SkiaBaseWebView<\n TProps extends SkiaBaseViewProps\n> extends React.Component<TProps> {\n constructor(props: TProps) {\n super(props);\n this._mode = props.mode ?? \"default\";\n }\n\n private _surface: JsiSkSurface | null = null;\n private _unsubscriptions: Array<() => void> = [];\n private _touches: Array<TouchInfo> = [];\n private _canvas: SkCanvas | null = null;\n private _canvasRef = React.createRef<HTMLCanvasElement>();\n private _mode: DrawMode;\n private _redrawRequests = 0;\n private requestId = 0;\n\n protected width = 0;\n protected height = 0;\n\n private unsubscribeAll() {\n this._unsubscriptions.forEach((u) => u());\n this._unsubscriptions = [];\n }\n\n private onLayout(evt: LayoutChangeEvent) {\n const { CanvasKit } = global;\n const { width, height } = evt.nativeEvent.layout;\n this.width = width;\n this.height = height;\n // Reset canvas / surface on layout change\n if (this._canvasRef.current) {\n const canvas = this._canvasRef.current;\n canvas.width = width * pd;\n canvas.height = height * pd;\n const surface = CanvasKit.MakeWebGLCanvasSurface(this._canvasRef.current);\n if (!surface) {\n throw new Error(\"Could not create surface\");\n }\n this._surface = new JsiSkSurface(CanvasKit, surface);\n this._canvas = this._surface.getCanvas();\n this.redraw();\n }\n // Call onLayout callback if it exists\n if (this.props.onLayout) {\n this.props.onLayout(evt);\n }\n }\n\n protected getSize() {\n return { width: this.width, height: this.height };\n }\n\n componentDidMount() {\n // Start render loop\n this.tick();\n }\n\n componentDidUpdate() {\n this.redraw();\n }\n\n componentWillUnmount() {\n this.unsubscribeAll();\n cancelAnimationFrame(this.requestId);\n }\n\n /**\n * Creates a snapshot from the canvas in the surface\n * @param rect Rect to use as bounds. Optional.\n * @returns An Image object.\n */\n public makeImageSnapshot(rect?: SkRect) {\n this._canvas!.clear(CanvasKit.TRANSPARENT);\n this.renderInCanvas(this._canvas!, []);\n this._surface?.ref.flush();\n return this._surface?.makeImageSnapshot(rect);\n }\n\n /**\n * Override to render\n */\n protected abstract renderInCanvas(\n canvas: SkCanvas,\n touches: TouchInfo[]\n ): void;\n\n /**\n * Sends a redraw request to the native SkiaView.\n */\n private tick() {\n if (this._mode === \"continuous\" || this._redrawRequests > 0) {\n this._redrawRequests = 0;\n if (this._canvas) {\n const touches = [...this._touches];\n this._touches = [];\n const canvas = this._canvas!;\n canvas.clear(Float32Array.of(0, 0, 0, 0));\n canvas.save();\n canvas.scale(pd, pd);\n this.renderInCanvas(canvas, touches);\n canvas.restore();\n this._surface?.ref.flush();\n }\n }\n this.requestId = requestAnimationFrame(this.tick.bind(this));\n }\n\n public redraw() {\n this._redrawRequests++;\n }\n\n /**\n * Updates the drawing mode for the skia view. This is the same\n * as declaratively setting the mode property on the SkiaView.\n * There are two drawing modes, \"continuous\" and \"default\",\n * where the continuous mode will continuously redraw the view and\n * the default mode will only redraw when any of the regular react\n * properties are changed like size and margins.\n * @param mode Drawing mode to use.\n */\n public setDrawMode(mode: DrawMode) {\n this._mode = mode;\n this.tick();\n }\n\n /**\n * Registers one or move values as a dependant value of the Skia View. The view will\n * The view will redraw itself when any of the values change.\n * @param values Values to register\n */\n public registerValues(_values: SkiaValue<unknown>[]) {\n // Unsubscribe from dependency values\n this.unsubscribeAll();\n // Register redraw dependencies on values\n _values.forEach((v) => {\n this._unsubscriptions.push(\n v.addListener(() => {\n this.redraw();\n })\n );\n });\n }\n\n private handleTouchEvent(evt: PointerEvent, touchType: TouchType) {\n this._touches.push({\n id: evt.pointerId,\n x: evt.clientX - evt.currentTarget.getClientRects()[0].left,\n y: evt.clientY - evt.currentTarget.getClientRects()[0].top,\n force: evt.pressure,\n type: touchType,\n timestamp: Date.now(),\n });\n this.redraw();\n }\n\n createTouchHandler(touchType: TouchType) {\n return (evt: PointerEvent) => this.handleTouchEvent(evt, touchType);\n }\n\n render() {\n const { mode, debug = false, ...viewProps } = this.props;\n return (\n <View {...viewProps} onLayout={this.onLayout.bind(this)}>\n <canvas\n ref={this._canvasRef}\n style={{ display: \"flex\", flex: 1 }}\n onPointerDown={this.createTouchHandler(TouchType.Start)}\n onPointerMove={this.createTouchHandler(TouchType.Active)}\n onPointerUp={this.createTouchHandler(TouchType.End)}\n onPointerCancel={this.createTouchHandler(TouchType.Cancelled)}\n onPointerLeave={this.createTouchHandler(TouchType.End)}\n onPointerOut={this.createTouchHandler(TouchType.End)}\n />\n </View>\n );\n }\n}\n"],"mappings":"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"}
|
1
|
+
{"version":3,"names":["pd","PixelRatio","get","SkiaBaseWebView","React","Component","constructor","props","createRef","_mode","mode","unsubscribeAll","_unsubscriptions","forEach","u","onLayout","evt","CanvasKit","global","width","height","nativeEvent","layout","_canvasRef","current","canvas","surface","MakeWebGLCanvasSurface","Error","_surface","JsiSkSurface","_canvas","getCanvas","redraw","getSize","componentDidMount","tick","componentDidUpdate","componentWillUnmount","cancelAnimationFrame","requestId","getContext","getExtension","loseContext","makeImageSnapshot","rect","clear","TRANSPARENT","renderInCanvas","ref","flush","_redrawRequests","touches","_touches","Float32Array","of","save","scale","restore","requestAnimationFrame","bind","setDrawMode","registerValues","_values","v","push","addListener","handleTouchEvent","touchType","id","pointerId","x","clientX","currentTarget","getClientRects","left","y","clientY","top","force","pressure","type","timestamp","Date","now","createTouchHandler","render","debug","viewProps","display","flex","TouchType","Start","Active","End","Cancelled"],"sources":["SkiaBaseWebView.tsx"],"sourcesContent":["/* global HTMLCanvasElement */\nimport React from \"react\";\nimport type { PointerEvent } from \"react\";\nimport type { LayoutChangeEvent } from \"react-native\";\nimport { PixelRatio, View } from \"react-native\";\n\nimport type { SkRect, SkCanvas } from \"../skia/types\";\nimport type { SkiaValue } from \"../values\";\nimport { JsiSkSurface } from \"../skia/web/JsiSkSurface\";\n\nimport type { DrawMode, SkiaBaseViewProps, TouchInfo } from \"./types\";\nimport { TouchType } from \"./types\";\n\nconst pd = PixelRatio.get();\n\nexport abstract class SkiaBaseWebView<\n TProps extends SkiaBaseViewProps\n> extends React.Component<TProps> {\n constructor(props: TProps) {\n super(props);\n this._mode = props.mode ?? \"default\";\n }\n\n private _surface: JsiSkSurface | null = null;\n private _unsubscriptions: Array<() => void> = [];\n private _touches: Array<TouchInfo> = [];\n private _canvas: SkCanvas | null = null;\n private _canvasRef = React.createRef<HTMLCanvasElement>();\n private _mode: DrawMode;\n private _redrawRequests = 0;\n private requestId = 0;\n\n protected width = 0;\n protected height = 0;\n\n private unsubscribeAll() {\n this._unsubscriptions.forEach((u) => u());\n this._unsubscriptions = [];\n }\n\n private onLayout(evt: LayoutChangeEvent) {\n const { CanvasKit } = global;\n const { width, height } = evt.nativeEvent.layout;\n this.width = width;\n this.height = height;\n // Reset canvas / surface on layout change\n if (this._canvasRef.current) {\n const canvas = this._canvasRef.current;\n canvas.width = width * pd;\n canvas.height = height * pd;\n const surface = CanvasKit.MakeWebGLCanvasSurface(this._canvasRef.current);\n if (!surface) {\n throw new Error(\"Could not create surface\");\n }\n this._surface = new JsiSkSurface(CanvasKit, surface);\n this._canvas = this._surface.getCanvas();\n this.redraw();\n }\n // Call onLayout callback if it exists\n if (this.props.onLayout) {\n this.props.onLayout(evt);\n }\n }\n\n protected getSize() {\n return { width: this.width, height: this.height };\n }\n\n componentDidMount() {\n // Start render loop\n this.tick();\n }\n\n componentDidUpdate() {\n this.redraw();\n }\n\n componentWillUnmount() {\n this.unsubscribeAll();\n cancelAnimationFrame(this.requestId);\n // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context\n this._canvasRef.current\n ?.getContext(\"webgl2\")\n ?.getExtension(\"WEBGL_lose_context\")\n ?.loseContext();\n }\n\n /**\n * Creates a snapshot from the canvas in the surface\n * @param rect Rect to use as bounds. Optional.\n * @returns An Image object.\n */\n public makeImageSnapshot(rect?: SkRect) {\n this._canvas!.clear(CanvasKit.TRANSPARENT);\n this.renderInCanvas(this._canvas!, []);\n this._surface?.ref.flush();\n return this._surface?.makeImageSnapshot(rect);\n }\n\n /**\n * Override to render\n */\n protected abstract renderInCanvas(\n canvas: SkCanvas,\n touches: TouchInfo[]\n ): void;\n\n /**\n * Sends a redraw request to the native SkiaView.\n */\n private tick() {\n if (this._mode === \"continuous\" || this._redrawRequests > 0) {\n this._redrawRequests = 0;\n if (this._canvas) {\n const touches = [...this._touches];\n this._touches = [];\n const canvas = this._canvas!;\n canvas.clear(Float32Array.of(0, 0, 0, 0));\n canvas.save();\n canvas.scale(pd, pd);\n this.renderInCanvas(canvas, touches);\n canvas.restore();\n this._surface?.ref.flush();\n }\n }\n this.requestId = requestAnimationFrame(this.tick.bind(this));\n }\n\n public redraw() {\n this._redrawRequests++;\n }\n\n /**\n * Updates the drawing mode for the skia view. This is the same\n * as declaratively setting the mode property on the SkiaView.\n * There are two drawing modes, \"continuous\" and \"default\",\n * where the continuous mode will continuously redraw the view and\n * the default mode will only redraw when any of the regular react\n * properties are changed like size and margins.\n * @param mode Drawing mode to use.\n */\n public setDrawMode(mode: DrawMode) {\n this._mode = mode;\n this.tick();\n }\n\n /**\n * Registers one or move values as a dependant value of the Skia View. The view will\n * The view will redraw itself when any of the values change.\n * @param values Values to register\n */\n public registerValues(_values: SkiaValue<unknown>[]) {\n // Unsubscribe from dependency values\n this.unsubscribeAll();\n // Register redraw dependencies on values\n _values.forEach((v) => {\n this._unsubscriptions.push(\n v.addListener(() => {\n this.redraw();\n })\n );\n });\n }\n\n private handleTouchEvent(evt: PointerEvent, touchType: TouchType) {\n this._touches.push({\n id: evt.pointerId,\n x: evt.clientX - evt.currentTarget.getClientRects()[0].left,\n y: evt.clientY - evt.currentTarget.getClientRects()[0].top,\n force: evt.pressure,\n type: touchType,\n timestamp: Date.now(),\n });\n this.redraw();\n }\n\n createTouchHandler(touchType: TouchType) {\n return (evt: PointerEvent) => this.handleTouchEvent(evt, touchType);\n }\n\n render() {\n const { mode, debug = false, ...viewProps } = this.props;\n return (\n <View {...viewProps} onLayout={this.onLayout.bind(this)}>\n <canvas\n ref={this._canvasRef}\n style={{ display: \"flex\", flex: 1 }}\n onPointerDown={this.createTouchHandler(TouchType.Start)}\n onPointerMove={this.createTouchHandler(TouchType.Active)}\n onPointerUp={this.createTouchHandler(TouchType.End)}\n onPointerCancel={this.createTouchHandler(TouchType.Cancelled)}\n onPointerLeave={this.createTouchHandler(TouchType.End)}\n onPointerOut={this.createTouchHandler(TouchType.End)}\n />\n </View>\n );\n }\n}\n"],"mappings":"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"}
|
@@ -92,8 +92,12 @@ export class SkiaBaseWebView extends React.Component {
|
|
92
92
|
}
|
93
93
|
|
94
94
|
componentWillUnmount() {
|
95
|
+
var _this$_canvasRef$curr, _this$_canvasRef$curr2, _this$_canvasRef$curr3;
|
96
|
+
|
95
97
|
this.unsubscribeAll();
|
96
|
-
cancelAnimationFrame(this.requestId);
|
98
|
+
cancelAnimationFrame(this.requestId); // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context
|
99
|
+
|
100
|
+
(_this$_canvasRef$curr = this._canvasRef.current) === null || _this$_canvasRef$curr === void 0 ? void 0 : (_this$_canvasRef$curr2 = _this$_canvasRef$curr.getContext("webgl2")) === null || _this$_canvasRef$curr2 === void 0 ? void 0 : (_this$_canvasRef$curr3 = _this$_canvasRef$curr2.getExtension("WEBGL_lose_context")) === null || _this$_canvasRef$curr3 === void 0 ? void 0 : _this$_canvasRef$curr3.loseContext();
|
97
101
|
}
|
98
102
|
/**
|
99
103
|
* Creates a snapshot from the canvas in the surface
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"names":["React","PixelRatio","View","JsiSkSurface","TouchType","pd","get","SkiaBaseWebView","Component","constructor","props","createRef","_mode","mode","unsubscribeAll","_unsubscriptions","forEach","u","onLayout","evt","CanvasKit","global","width","height","nativeEvent","layout","_canvasRef","current","canvas","surface","MakeWebGLCanvasSurface","Error","_surface","_canvas","getCanvas","redraw","getSize","componentDidMount","tick","componentDidUpdate","componentWillUnmount","cancelAnimationFrame","requestId","makeImageSnapshot","rect","clear","TRANSPARENT","renderInCanvas","ref","flush","_redrawRequests","touches","_touches","Float32Array","of","save","scale","restore","requestAnimationFrame","bind","setDrawMode","registerValues","_values","v","push","addListener","handleTouchEvent","touchType","id","pointerId","x","clientX","currentTarget","getClientRects","left","y","clientY","top","force","pressure","type","timestamp","Date","now","createTouchHandler","render","debug","viewProps","display","flex","Start","Active","End","Cancelled"],"sources":["SkiaBaseWebView.tsx"],"sourcesContent":["/* global HTMLCanvasElement */\nimport React from \"react\";\nimport type { PointerEvent } from \"react\";\nimport type { LayoutChangeEvent } from \"react-native\";\nimport { PixelRatio, View } from \"react-native\";\n\nimport type { SkRect, SkCanvas } from \"../skia/types\";\nimport type { SkiaValue } from \"../values\";\nimport { JsiSkSurface } from \"../skia/web/JsiSkSurface\";\n\nimport type { DrawMode, SkiaBaseViewProps, TouchInfo } from \"./types\";\nimport { TouchType } from \"./types\";\n\nconst pd = PixelRatio.get();\n\nexport abstract class SkiaBaseWebView<\n TProps extends SkiaBaseViewProps\n> extends React.Component<TProps> {\n constructor(props: TProps) {\n super(props);\n this._mode = props.mode ?? \"default\";\n }\n\n private _surface: JsiSkSurface | null = null;\n private _unsubscriptions: Array<() => void> = [];\n private _touches: Array<TouchInfo> = [];\n private _canvas: SkCanvas | null = null;\n private _canvasRef = React.createRef<HTMLCanvasElement>();\n private _mode: DrawMode;\n private _redrawRequests = 0;\n private requestId = 0;\n\n protected width = 0;\n protected height = 0;\n\n private unsubscribeAll() {\n this._unsubscriptions.forEach((u) => u());\n this._unsubscriptions = [];\n }\n\n private onLayout(evt: LayoutChangeEvent) {\n const { CanvasKit } = global;\n const { width, height } = evt.nativeEvent.layout;\n this.width = width;\n this.height = height;\n // Reset canvas / surface on layout change\n if (this._canvasRef.current) {\n const canvas = this._canvasRef.current;\n canvas.width = width * pd;\n canvas.height = height * pd;\n const surface = CanvasKit.MakeWebGLCanvasSurface(this._canvasRef.current);\n if (!surface) {\n throw new Error(\"Could not create surface\");\n }\n this._surface = new JsiSkSurface(CanvasKit, surface);\n this._canvas = this._surface.getCanvas();\n this.redraw();\n }\n // Call onLayout callback if it exists\n if (this.props.onLayout) {\n this.props.onLayout(evt);\n }\n }\n\n protected getSize() {\n return { width: this.width, height: this.height };\n }\n\n componentDidMount() {\n // Start render loop\n this.tick();\n }\n\n componentDidUpdate() {\n this.redraw();\n }\n\n componentWillUnmount() {\n this.unsubscribeAll();\n cancelAnimationFrame(this.requestId);\n }\n\n /**\n * Creates a snapshot from the canvas in the surface\n * @param rect Rect to use as bounds. Optional.\n * @returns An Image object.\n */\n public makeImageSnapshot(rect?: SkRect) {\n this._canvas!.clear(CanvasKit.TRANSPARENT);\n this.renderInCanvas(this._canvas!, []);\n this._surface?.ref.flush();\n return this._surface?.makeImageSnapshot(rect);\n }\n\n /**\n * Override to render\n */\n protected abstract renderInCanvas(\n canvas: SkCanvas,\n touches: TouchInfo[]\n ): void;\n\n /**\n * Sends a redraw request to the native SkiaView.\n */\n private tick() {\n if (this._mode === \"continuous\" || this._redrawRequests > 0) {\n this._redrawRequests = 0;\n if (this._canvas) {\n const touches = [...this._touches];\n this._touches = [];\n const canvas = this._canvas!;\n canvas.clear(Float32Array.of(0, 0, 0, 0));\n canvas.save();\n canvas.scale(pd, pd);\n this.renderInCanvas(canvas, touches);\n canvas.restore();\n this._surface?.ref.flush();\n }\n }\n this.requestId = requestAnimationFrame(this.tick.bind(this));\n }\n\n public redraw() {\n this._redrawRequests++;\n }\n\n /**\n * Updates the drawing mode for the skia view. This is the same\n * as declaratively setting the mode property on the SkiaView.\n * There are two drawing modes, \"continuous\" and \"default\",\n * where the continuous mode will continuously redraw the view and\n * the default mode will only redraw when any of the regular react\n * properties are changed like size and margins.\n * @param mode Drawing mode to use.\n */\n public setDrawMode(mode: DrawMode) {\n this._mode = mode;\n this.tick();\n }\n\n /**\n * Registers one or move values as a dependant value of the Skia View. The view will\n * The view will redraw itself when any of the values change.\n * @param values Values to register\n */\n public registerValues(_values: SkiaValue<unknown>[]) {\n // Unsubscribe from dependency values\n this.unsubscribeAll();\n // Register redraw dependencies on values\n _values.forEach((v) => {\n this._unsubscriptions.push(\n v.addListener(() => {\n this.redraw();\n })\n );\n });\n }\n\n private handleTouchEvent(evt: PointerEvent, touchType: TouchType) {\n this._touches.push({\n id: evt.pointerId,\n x: evt.clientX - evt.currentTarget.getClientRects()[0].left,\n y: evt.clientY - evt.currentTarget.getClientRects()[0].top,\n force: evt.pressure,\n type: touchType,\n timestamp: Date.now(),\n });\n this.redraw();\n }\n\n createTouchHandler(touchType: TouchType) {\n return (evt: PointerEvent) => this.handleTouchEvent(evt, touchType);\n }\n\n render() {\n const { mode, debug = false, ...viewProps } = this.props;\n return (\n <View {...viewProps} onLayout={this.onLayout.bind(this)}>\n <canvas\n ref={this._canvasRef}\n style={{ display: \"flex\", flex: 1 }}\n onPointerDown={this.createTouchHandler(TouchType.Start)}\n onPointerMove={this.createTouchHandler(TouchType.Active)}\n onPointerUp={this.createTouchHandler(TouchType.End)}\n onPointerCancel={this.createTouchHandler(TouchType.Cancelled)}\n onPointerLeave={this.createTouchHandler(TouchType.End)}\n onPointerOut={this.createTouchHandler(TouchType.End)}\n />\n </View>\n );\n }\n}\n"],"mappings":"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"}
|
1
|
+
{"version":3,"names":["React","PixelRatio","View","JsiSkSurface","TouchType","pd","get","SkiaBaseWebView","Component","constructor","props","createRef","_mode","mode","unsubscribeAll","_unsubscriptions","forEach","u","onLayout","evt","CanvasKit","global","width","height","nativeEvent","layout","_canvasRef","current","canvas","surface","MakeWebGLCanvasSurface","Error","_surface","_canvas","getCanvas","redraw","getSize","componentDidMount","tick","componentDidUpdate","componentWillUnmount","cancelAnimationFrame","requestId","getContext","getExtension","loseContext","makeImageSnapshot","rect","clear","TRANSPARENT","renderInCanvas","ref","flush","_redrawRequests","touches","_touches","Float32Array","of","save","scale","restore","requestAnimationFrame","bind","setDrawMode","registerValues","_values","v","push","addListener","handleTouchEvent","touchType","id","pointerId","x","clientX","currentTarget","getClientRects","left","y","clientY","top","force","pressure","type","timestamp","Date","now","createTouchHandler","render","debug","viewProps","display","flex","Start","Active","End","Cancelled"],"sources":["SkiaBaseWebView.tsx"],"sourcesContent":["/* global HTMLCanvasElement */\nimport React from \"react\";\nimport type { PointerEvent } from \"react\";\nimport type { LayoutChangeEvent } from \"react-native\";\nimport { PixelRatio, View } from \"react-native\";\n\nimport type { SkRect, SkCanvas } from \"../skia/types\";\nimport type { SkiaValue } from \"../values\";\nimport { JsiSkSurface } from \"../skia/web/JsiSkSurface\";\n\nimport type { DrawMode, SkiaBaseViewProps, TouchInfo } from \"./types\";\nimport { TouchType } from \"./types\";\n\nconst pd = PixelRatio.get();\n\nexport abstract class SkiaBaseWebView<\n TProps extends SkiaBaseViewProps\n> extends React.Component<TProps> {\n constructor(props: TProps) {\n super(props);\n this._mode = props.mode ?? \"default\";\n }\n\n private _surface: JsiSkSurface | null = null;\n private _unsubscriptions: Array<() => void> = [];\n private _touches: Array<TouchInfo> = [];\n private _canvas: SkCanvas | null = null;\n private _canvasRef = React.createRef<HTMLCanvasElement>();\n private _mode: DrawMode;\n private _redrawRequests = 0;\n private requestId = 0;\n\n protected width = 0;\n protected height = 0;\n\n private unsubscribeAll() {\n this._unsubscriptions.forEach((u) => u());\n this._unsubscriptions = [];\n }\n\n private onLayout(evt: LayoutChangeEvent) {\n const { CanvasKit } = global;\n const { width, height } = evt.nativeEvent.layout;\n this.width = width;\n this.height = height;\n // Reset canvas / surface on layout change\n if (this._canvasRef.current) {\n const canvas = this._canvasRef.current;\n canvas.width = width * pd;\n canvas.height = height * pd;\n const surface = CanvasKit.MakeWebGLCanvasSurface(this._canvasRef.current);\n if (!surface) {\n throw new Error(\"Could not create surface\");\n }\n this._surface = new JsiSkSurface(CanvasKit, surface);\n this._canvas = this._surface.getCanvas();\n this.redraw();\n }\n // Call onLayout callback if it exists\n if (this.props.onLayout) {\n this.props.onLayout(evt);\n }\n }\n\n protected getSize() {\n return { width: this.width, height: this.height };\n }\n\n componentDidMount() {\n // Start render loop\n this.tick();\n }\n\n componentDidUpdate() {\n this.redraw();\n }\n\n componentWillUnmount() {\n this.unsubscribeAll();\n cancelAnimationFrame(this.requestId);\n // https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context\n this._canvasRef.current\n ?.getContext(\"webgl2\")\n ?.getExtension(\"WEBGL_lose_context\")\n ?.loseContext();\n }\n\n /**\n * Creates a snapshot from the canvas in the surface\n * @param rect Rect to use as bounds. Optional.\n * @returns An Image object.\n */\n public makeImageSnapshot(rect?: SkRect) {\n this._canvas!.clear(CanvasKit.TRANSPARENT);\n this.renderInCanvas(this._canvas!, []);\n this._surface?.ref.flush();\n return this._surface?.makeImageSnapshot(rect);\n }\n\n /**\n * Override to render\n */\n protected abstract renderInCanvas(\n canvas: SkCanvas,\n touches: TouchInfo[]\n ): void;\n\n /**\n * Sends a redraw request to the native SkiaView.\n */\n private tick() {\n if (this._mode === \"continuous\" || this._redrawRequests > 0) {\n this._redrawRequests = 0;\n if (this._canvas) {\n const touches = [...this._touches];\n this._touches = [];\n const canvas = this._canvas!;\n canvas.clear(Float32Array.of(0, 0, 0, 0));\n canvas.save();\n canvas.scale(pd, pd);\n this.renderInCanvas(canvas, touches);\n canvas.restore();\n this._surface?.ref.flush();\n }\n }\n this.requestId = requestAnimationFrame(this.tick.bind(this));\n }\n\n public redraw() {\n this._redrawRequests++;\n }\n\n /**\n * Updates the drawing mode for the skia view. This is the same\n * as declaratively setting the mode property on the SkiaView.\n * There are two drawing modes, \"continuous\" and \"default\",\n * where the continuous mode will continuously redraw the view and\n * the default mode will only redraw when any of the regular react\n * properties are changed like size and margins.\n * @param mode Drawing mode to use.\n */\n public setDrawMode(mode: DrawMode) {\n this._mode = mode;\n this.tick();\n }\n\n /**\n * Registers one or move values as a dependant value of the Skia View. The view will\n * The view will redraw itself when any of the values change.\n * @param values Values to register\n */\n public registerValues(_values: SkiaValue<unknown>[]) {\n // Unsubscribe from dependency values\n this.unsubscribeAll();\n // Register redraw dependencies on values\n _values.forEach((v) => {\n this._unsubscriptions.push(\n v.addListener(() => {\n this.redraw();\n })\n );\n });\n }\n\n private handleTouchEvent(evt: PointerEvent, touchType: TouchType) {\n this._touches.push({\n id: evt.pointerId,\n x: evt.clientX - evt.currentTarget.getClientRects()[0].left,\n y: evt.clientY - evt.currentTarget.getClientRects()[0].top,\n force: evt.pressure,\n type: touchType,\n timestamp: Date.now(),\n });\n this.redraw();\n }\n\n createTouchHandler(touchType: TouchType) {\n return (evt: PointerEvent) => this.handleTouchEvent(evt, touchType);\n }\n\n render() {\n const { mode, debug = false, ...viewProps } = this.props;\n return (\n <View {...viewProps} onLayout={this.onLayout.bind(this)}>\n <canvas\n ref={this._canvasRef}\n style={{ display: \"flex\", flex: 1 }}\n onPointerDown={this.createTouchHandler(TouchType.Start)}\n onPointerMove={this.createTouchHandler(TouchType.Active)}\n onPointerUp={this.createTouchHandler(TouchType.End)}\n onPointerCancel={this.createTouchHandler(TouchType.Cancelled)}\n onPointerLeave={this.createTouchHandler(TouchType.End)}\n onPointerOut={this.createTouchHandler(TouchType.End)}\n />\n </View>\n );\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
@@ -78,6 +78,11 @@ export abstract class SkiaBaseWebView<
|
|
78
78
|
componentWillUnmount() {
|
79
79
|
this.unsubscribeAll();
|
80
80
|
cancelAnimationFrame(this.requestId);
|
81
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/WEBGL_lose_context
|
82
|
+
this._canvasRef.current
|
83
|
+
?.getContext("webgl2")
|
84
|
+
?.getExtension("WEBGL_lose_context")
|
85
|
+
?.loseContext();
|
81
86
|
}
|
82
87
|
|
83
88
|
/**
|