@shopify/react-native-skia 0.1.187 → 0.1.189

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.
Files changed (44) hide show
  1. package/android/build.gradle +15 -2
  2. package/cpp/api/JsiSkMatrix.h +6 -6
  3. package/cpp/rnskia/dom/base/JsiDependencyManager.h +47 -47
  4. package/cpp/rnskia/dom/base/JsiDomNode.h +6 -7
  5. package/cpp/rnskia/dom/base/NodePropsContainer.h +27 -3
  6. package/cpp/rnskia/dom/props/ColorProp.h +7 -0
  7. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.h +10 -9
  8. package/ios/RNSkia-iOS/RNSkiOSPlatformContext.mm +7 -3
  9. package/ios/RNSkia-iOS/SkiaManager.mm +3 -27
  10. package/ios/RNSkia-iOS/ViewScreenshotService.mm +13 -1
  11. package/lib/commonjs/animation/functions/interpolateColors.d.ts +1 -1
  12. package/lib/commonjs/animation/functions/interpolateColors.js +3 -2
  13. package/lib/commonjs/animation/functions/interpolateColors.js.map +1 -1
  14. package/lib/commonjs/skia/types/Color.d.ts +1 -1
  15. package/lib/commonjs/skia/types/Color.js.map +1 -1
  16. package/lib/commonjs/skia/types/Matrix.d.ts +6 -6
  17. package/lib/commonjs/skia/types/Matrix.js.map +1 -1
  18. package/lib/commonjs/skia/web/JsiSkColor.js +2 -0
  19. package/lib/commonjs/skia/web/JsiSkColor.js.map +1 -1
  20. package/lib/commonjs/skia/web/JsiSkMatrix.d.ts +6 -6
  21. package/lib/commonjs/skia/web/JsiSkMatrix.js +6 -0
  22. package/lib/commonjs/skia/web/JsiSkMatrix.js.map +1 -1
  23. package/lib/module/animation/functions/interpolateColors.d.ts +1 -1
  24. package/lib/module/animation/functions/interpolateColors.js +3 -2
  25. package/lib/module/animation/functions/interpolateColors.js.map +1 -1
  26. package/lib/module/skia/types/Color.d.ts +1 -1
  27. package/lib/module/skia/types/Color.js.map +1 -1
  28. package/lib/module/skia/types/Matrix.d.ts +6 -6
  29. package/lib/module/skia/types/Matrix.js.map +1 -1
  30. package/lib/module/skia/web/JsiSkColor.js +2 -0
  31. package/lib/module/skia/web/JsiSkColor.js.map +1 -1
  32. package/lib/module/skia/web/JsiSkMatrix.d.ts +6 -6
  33. package/lib/module/skia/web/JsiSkMatrix.js +6 -0
  34. package/lib/module/skia/web/JsiSkMatrix.js.map +1 -1
  35. package/lib/typescript/src/animation/functions/interpolateColors.d.ts +1 -1
  36. package/lib/typescript/src/skia/types/Color.d.ts +1 -1
  37. package/lib/typescript/src/skia/types/Matrix.d.ts +6 -6
  38. package/lib/typescript/src/skia/web/JsiSkMatrix.d.ts +6 -6
  39. package/package.json +1 -1
  40. package/src/animation/functions/interpolateColors.ts +2 -1
  41. package/src/skia/types/Color.ts +1 -1
  42. package/src/skia/types/Matrix.ts +6 -6
  43. package/src/skia/web/JsiSkColor.ts +2 -0
  44. package/src/skia/web/JsiSkMatrix.ts +6 -0
@@ -272,11 +272,24 @@ task extractJNIFiles {
272
272
  extractJNIFiles.mustRunAfter extractAARHeaders
273
273
 
274
274
  if (ENABLE_PREFAB) {
275
- // Package everything with the original file structure
275
+ // Package all the cpp code in a flattened directory structure
276
276
  task prepareHeaders(type: Copy) {
277
- from('./cpp')
277
+ from("./cpp")
278
278
  into "${project.buildDir}/headers/rnskia/"
279
279
  includeEmptyDirs = false
280
+ include "**/*.h"
281
+ eachFile {
282
+ String path = it.path
283
+
284
+ // Skip flattening third_party dir
285
+ if (path.contains("api/third_party")) {
286
+ path = path.substring("api/".length())
287
+ } else {
288
+ // flatten anything else
289
+ path = path.substring(path.lastIndexOf("/") + 1)
290
+ }
291
+ it.path = path
292
+ }
280
293
  }
281
294
  preBuild.dependsOn(prepareHeaders)
282
295
  }
@@ -47,39 +47,39 @@ public:
47
47
  JSI_HOST_FUNCTION(concat) {
48
48
  auto m3 = JsiSkMatrix::fromValue(runtime, arguments[0]);
49
49
  getObject()->preConcat(*m3);
50
- return jsi::Value::undefined();
50
+ return thisValue.asObject(runtime);
51
51
  }
52
52
 
53
53
  JSI_HOST_FUNCTION(translate) {
54
54
  auto x = arguments[0].asNumber();
55
55
  auto y = arguments[1].asNumber();
56
56
  getObject()->preTranslate(x, y);
57
- return jsi::Value::undefined();
57
+ return thisValue.asObject(runtime);
58
58
  }
59
59
 
60
60
  JSI_HOST_FUNCTION(scale) {
61
61
  auto x = arguments[0].asNumber();
62
62
  auto y = count > 1 ? arguments[1].asNumber() : 1;
63
63
  getObject()->preScale(x, y);
64
- return jsi::Value::undefined();
64
+ return thisValue.asObject(runtime);
65
65
  }
66
66
 
67
67
  JSI_HOST_FUNCTION(skew) {
68
68
  auto x = arguments[0].asNumber();
69
69
  auto y = arguments[1].asNumber();
70
70
  getObject()->preSkew(x, y);
71
- return jsi::Value::undefined();
71
+ return thisValue.asObject(runtime);
72
72
  }
73
73
 
74
74
  JSI_HOST_FUNCTION(rotate) {
75
75
  auto a = arguments[0].asNumber();
76
76
  getObject()->preRotate(SkRadiansToDegrees(a));
77
- return jsi::Value::undefined();
77
+ return thisValue.asObject(runtime);
78
78
  }
79
79
 
80
80
  JSI_HOST_FUNCTION(identity) {
81
81
  getObject()->setIdentity();
82
- return jsi::Value::undefined();
82
+ return thisValue.asObject(runtime);
83
83
  }
84
84
 
85
85
  JSI_HOST_FUNCTION(get) {
@@ -64,53 +64,53 @@ public:
64
64
 
65
65
  // Enumerate registered keys for the given node to only handle known
66
66
  // properties
67
- for (const auto &propMapping :
68
- node->getPropsContainer()->getMappedProperties()) {
69
- auto key = propMapping.first;
70
- auto jsValue = nextProps.getProperty(runtime, key);
71
- JsiValue nativeValue(runtime, jsValue);
72
-
73
- if (isAnimatedValue(nativeValue)) {
74
- // Handle Skia Animation Values
75
- auto animatedValue = getAnimatedValue(nativeValue);
76
- auto unsubscribe = animatedValue->addListener(
77
- [animatedValue, propMapping](jsi::Runtime &runtime) {
78
- // Get value from animation value
79
- auto nextJsValue = animatedValue->getCurrent(runtime);
80
- // Update all props that listens to this animation value
81
- for (auto &prop : propMapping.second) {
82
- prop->updateValue(runtime, nextJsValue);
83
- }
84
- });
85
-
86
- // Save unsubscribe methods
87
- unsubscribers.push_back(std::make_pair(animatedValue, unsubscribe));
88
-
89
- } else if (isSelector(nativeValue)) {
90
- // Handle Skia Animation Value Selectors
91
- auto animatedValue = std::dynamic_pointer_cast<RNSkReadonlyValue>(
92
- nativeValue.getValue(PropNameValue).getAsHostObject());
93
-
94
- auto selector = nativeValue.getValue(PropNameSelector).getAsFunction();
95
- // Add subscription to animated value in selector
96
- auto unsubscribe = animatedValue->addListener(
97
- [nativeValue, propMapping, selector = std::move(selector),
98
- animatedValue](jsi::Runtime &runtime) {
99
- // Get value from animation value
100
- jsi::Value jsValue = animatedValue->getCurrent(runtime);
101
- // Call selector to transform new value
102
- auto selectedJsValue =
103
- selector(runtime, jsi::Value::null(), &jsValue, 1);
104
- // Update all props that listens to this animation value
105
- for (auto &prop : propMapping.second) {
106
- prop->updateValue(runtime, selectedJsValue);
107
- }
108
- });
109
-
110
- // Save unsubscribe methods
111
- unsubscribers.push_back(std::make_pair(animatedValue, unsubscribe));
112
- }
113
- }
67
+ node->getPropsContainer()->enumerateMappedProps(
68
+ [&](const PropId key, const std::vector<NodeProp *> &propMapping) {
69
+ auto jsValue = nextProps.getProperty(runtime, key);
70
+ JsiValue nativeValue(runtime, jsValue);
71
+
72
+ if (isAnimatedValue(nativeValue)) {
73
+ // Handle Skia Animation Values
74
+ auto animatedValue = getAnimatedValue(nativeValue);
75
+ auto unsubscribe = animatedValue->addListener(
76
+ [animatedValue, propMapping](jsi::Runtime &runtime) {
77
+ // Get value from animation value
78
+ auto nextJsValue = animatedValue->getCurrent(runtime);
79
+ // Update all props that listens to this animation value
80
+ for (auto &prop : propMapping) {
81
+ prop->updateValue(runtime, nextJsValue);
82
+ }
83
+ });
84
+
85
+ // Save unsubscribe methods
86
+ unsubscribers.push_back(std::make_pair(animatedValue, unsubscribe));
87
+
88
+ } else if (isSelector(nativeValue)) {
89
+ // Handle Skia Animation Value Selectors
90
+ auto animatedValue = std::dynamic_pointer_cast<RNSkReadonlyValue>(
91
+ nativeValue.getValue(PropNameValue).getAsHostObject());
92
+
93
+ auto selector =
94
+ nativeValue.getValue(PropNameSelector).getAsFunction();
95
+ // Add subscription to animated value in selector
96
+ auto unsubscribe = animatedValue->addListener(
97
+ [nativeValue, propMapping, selector = std::move(selector),
98
+ animatedValue](jsi::Runtime &runtime) {
99
+ // Get value from animation value
100
+ jsi::Value jsValue = animatedValue->getCurrent(runtime);
101
+ // Call selector to transform new value
102
+ auto selectedJsValue =
103
+ selector(runtime, jsi::Value::null(), &jsValue, 1);
104
+ // Update all props that listens to this animation value
105
+ for (auto &prop : propMapping) {
106
+ prop->updateValue(runtime, selectedJsValue);
107
+ }
108
+ });
109
+
110
+ // Save unsubscribe methods
111
+ unsubscribers.push_back(std::make_pair(animatedValue, unsubscribe));
112
+ }
113
+ });
114
114
 
115
115
  // Now let's store the subscription info
116
116
  _subscriptions.emplace(node.get(), unsubscribers);
@@ -98,13 +98,12 @@ public:
98
98
  auto propName = arguments[0].asString(runtime).utf8(runtime);
99
99
  const jsi::Value &propValue = arguments[1];
100
100
 
101
- auto mappedProps = _propsContainer->getMappedProperties();
102
- auto propMapIt = mappedProps.find(JsiPropId::get(propName));
103
- if (propMapIt != mappedProps.end()) {
104
- for (auto &prop : propMapIt->second) {
105
- prop->updateValue(runtime, propValue);
106
- }
107
- }
101
+ // Enumerate all props with this name and update. The
102
+ // enumerateMappedPropsByName function is thread safe and locks props so it
103
+ // can be called from all threads.
104
+ _propsContainer->enumerateMappedPropsByName(propName, [&](NodeProp *prop) {
105
+ prop->updateValue(runtime, propValue);
106
+ });
108
107
 
109
108
  return jsi::Value::undefined();
110
109
  }
@@ -41,10 +41,30 @@ public:
41
41
  }
42
42
 
43
43
  /**
44
- Returns a list of mappings betwen property names and property objects
44
+ Enumerate all mapped properties
45
45
  */
46
- const std::map<PropId, std::vector<NodeProp *>> &getMappedProperties() {
47
- return _mappedProperties;
46
+ void enumerateMappedProps(
47
+ const std::function<void(const PropId name,
48
+ const std::vector<NodeProp *>)> &callback) {
49
+ std::lock_guard<std::mutex> lock(_mappedPropsLock);
50
+ for (auto &props : _mappedProperties) {
51
+ callback(props.first, props.second);
52
+ }
53
+ }
54
+
55
+ /**
56
+ Enumerates a named property instances from the mapped properties list
57
+ */
58
+ void
59
+ enumerateMappedPropsByName(const std::string &name,
60
+ const std::function<void(NodeProp *)> &callback) {
61
+ std::lock_guard<std::mutex> lock(_mappedPropsLock);
62
+ auto propMapIt = _mappedProperties.find(JsiPropId::get(name));
63
+ if (propMapIt != _mappedProperties.end()) {
64
+ for (auto &prop : propMapIt->second) {
65
+ callback(prop);
66
+ }
67
+ }
48
68
  }
49
69
 
50
70
  /**
@@ -75,6 +95,7 @@ public:
75
95
  Clears all props and data from the container
76
96
  */
77
97
  void dispose() {
98
+ std::lock_guard<std::mutex> lock(_mappedPropsLock);
78
99
  _properties.clear();
79
100
  _mappedProperties.clear();
80
101
  }
@@ -83,6 +104,8 @@ public:
83
104
  Called when the React / JS side sets properties on a node
84
105
  */
85
106
  void setProps(jsi::Runtime &runtime, const jsi::Value &maybePropsObject) {
107
+ std::lock_guard<std::mutex> lock(_mappedPropsLock);
108
+
86
109
  // Clear property mapping
87
110
  _mappedProperties.clear();
88
111
 
@@ -129,6 +152,7 @@ private:
129
152
  std::vector<std::shared_ptr<BaseNodeProp>> _properties;
130
153
  std::map<PropId, std::vector<NodeProp *>> _mappedProperties;
131
154
  PropId _type;
155
+ std::mutex _mappedPropsLock;
132
156
  };
133
157
 
134
158
  } // namespace RNSkia
@@ -42,6 +42,13 @@ public:
42
42
  return SkColorSetARGB(a.getAsNumber() * 255.0f, r.getAsNumber() * 255.0f,
43
43
  g.getAsNumber() * 255.0f, b.getAsNumber() * 255.0f);
44
44
 
45
+ } else if (color.getType() == PropType::Array) {
46
+ auto r = color.getAsArray().at(0);
47
+ auto g = color.getAsArray().at(1);
48
+ auto b = color.getAsArray().at(2);
49
+ auto a = color.getAsArray().at(3);
50
+ return SkColorSetARGB(a.getAsNumber() * 255.0f, r.getAsNumber() * 255.0f,
51
+ g.getAsNumber() * 255.0f, b.getAsNumber() * 255.0f);
45
52
  } else if (color.getType() == PropType::Number) {
46
53
  return static_cast<SkColor>(color.getAsNumber());
47
54
  } else {
@@ -1,6 +1,8 @@
1
1
  #pragma once
2
2
 
3
+ #import <React/RCTBridge+Private.h>
3
4
  #import <React/RCTBridge.h>
5
+ #import <ReactCommon/RCTTurboModule.h>
4
6
 
5
7
  #include <functional>
6
8
  #include <memory>
@@ -8,6 +10,7 @@
8
10
 
9
11
  #include "DisplayLink.h"
10
12
  #include "RNSkPlatformContext.h"
13
+ #include "ViewScreenshotService.h"
11
14
 
12
15
  #include <jsi/jsi.h>
13
16
 
@@ -27,13 +30,8 @@ static void handleNotification(CFNotificationCenterRef center, void *observer,
27
30
 
28
31
  class RNSkiOSPlatformContext : public RNSkPlatformContext {
29
32
  public:
30
- RNSkiOSPlatformContext(
31
- jsi::Runtime *runtime, std::shared_ptr<react::CallInvoker> callInvoker,
32
- std::function<void(std::function<void()>)> dispatchMainThread,
33
- std::function<sk_sp<SkImage>(size_t viewTag)> takeViewScreenshot)
34
- : _dispatchMainThread(dispatchMainThread),
35
- _takeViewScreenshot(takeViewScreenshot),
36
- RNSkPlatformContext(runtime, callInvoker,
33
+ RNSkiOSPlatformContext(jsi::Runtime *runtime, RCTBridge *bridge)
34
+ : RNSkPlatformContext(runtime, bridge.jsCallInvoker,
37
35
  [[UIScreen mainScreen] scale]) {
38
36
 
39
37
  // We need to make sure we invalidate when modules are freed
@@ -41,6 +39,10 @@ public:
41
39
  CFNotificationCenterGetLocalCenter(), this, &handleNotification,
42
40
  (__bridge CFStringRef)RCTBridgeWillInvalidateModulesNotification, NULL,
43
41
  CFNotificationSuspensionBehaviorDeliverImmediately);
42
+
43
+ // Create screenshot manager
44
+ _screenshotService =
45
+ [[ViewScreenshotService alloc] initWithUiManager:bridge.uiManager];
44
46
  }
45
47
 
46
48
  ~RNSkiOSPlatformContext() {
@@ -70,8 +72,7 @@ public:
70
72
 
71
73
  private:
72
74
  DisplayLink *_displayLink;
73
- std::function<void(std::function<void()>)> _dispatchMainThread;
74
- std::function<sk_sp<SkImage>(size_t viewTag)> _takeViewScreenshot;
75
+ ViewScreenshotService *_screenshotService;
75
76
  };
76
77
 
77
78
  static void handleNotification(CFNotificationCenterRef center, void *observer,
@@ -63,11 +63,15 @@ sk_sp<SkSurface> RNSkiOSPlatformContext::makeOffscreenSurface(int width,
63
63
  }
64
64
 
65
65
  void RNSkiOSPlatformContext::runOnMainThread(std::function<void()> func) {
66
- _dispatchMainThread(func);
66
+ dispatch_async(dispatch_get_main_queue(), ^{
67
+ func();
68
+ });
67
69
  }
68
70
 
69
- sk_sp<SkImage> RNSkiOSPlatformContext::takeScreenshotFromViewTag(size_t tag) {
70
- return _takeViewScreenshot(tag);
71
+ sk_sp<SkImage>
72
+ RNSkiOSPlatformContext::takeScreenshotFromViewTag(size_t viewTag) {
73
+ return [_screenshotService
74
+ screenshotOfViewWithTag:[NSNumber numberWithLong:viewTag]];
71
75
  }
72
76
 
73
77
  void RNSkiOSPlatformContext::startDrawLoop() {
@@ -9,12 +9,9 @@
9
9
  #import <ReactCommon/RCTTurboModule.h>
10
10
 
11
11
  #import "RNSkiOSPlatformContext.h"
12
- #import "ViewScreenshotService.h"
13
12
 
14
13
  @implementation SkiaManager {
15
14
  std::shared_ptr<RNSkia::RNSkManager> _skManager;
16
- std::shared_ptr<RNSkia::RNSkiOSPlatformContext> _platformContext;
17
- ViewScreenshotService *_screenshot;
18
15
  __weak RCTBridge *weakBridge;
19
16
  }
20
17
 
@@ -27,7 +24,6 @@
27
24
  _skManager->invalidate();
28
25
  }
29
26
  _skManager = nullptr;
30
- _platformContext = nullptr;
31
27
  }
32
28
 
33
29
  - (instancetype)initWithBridge:(RCTBridge *)bridge {
@@ -36,33 +32,13 @@
36
32
  RCTCxxBridge *cxxBridge = (RCTCxxBridge *)bridge;
37
33
  if (cxxBridge.runtime) {
38
34
 
39
- auto callInvoker = bridge.jsCallInvoker;
40
35
  facebook::jsi::Runtime *jsRuntime =
41
36
  (facebook::jsi::Runtime *)cxxBridge.runtime;
42
37
 
43
- // Create screenshot manager
44
- _screenshot =
45
- [[ViewScreenshotService alloc] initWithUiManager:bridge.uiManager];
46
-
47
- auto takeScreenshot = [self](size_t viewTag) {
48
- return [_screenshot
49
- screenshotOfViewWithTag:[NSNumber numberWithLong:viewTag]];
50
- };
51
-
52
- auto dispatchOnMainThread = [self](std::function<void()> fp) {
53
- dispatch_async(dispatch_get_main_queue(), ^{
54
- fp();
55
- });
56
- };
57
-
58
- // Create platform context
59
- _platformContext = std::make_shared<RNSkia::RNSkiOSPlatformContext>(
60
- jsRuntime, callInvoker, std::move(dispatchOnMainThread),
61
- std::move(takeScreenshot));
62
-
63
38
  // Create the RNSkiaManager (cross platform)
64
- _skManager = std::make_shared<RNSkia::RNSkManager>(jsRuntime, callInvoker,
65
- _platformContext);
39
+ _skManager = std::make_shared<RNSkia::RNSkManager>(
40
+ jsRuntime, bridge.jsCallInvoker,
41
+ std::make_shared<RNSkia::RNSkiOSPlatformContext>(jsRuntime, bridge));
66
42
  }
67
43
  }
68
44
  return self;
@@ -33,6 +33,15 @@
33
33
  UIGraphicsImageRendererFormat *format =
34
34
  [UIGraphicsImageRendererFormat defaultFormat];
35
35
  format.opaque = NO;
36
+
37
+ // Explicitly ask for the standard format to get ARGB 32bits and not 64bits.
38
+ if (@available(iOS 12.0, *)) {
39
+ format.preferredRange = UIGraphicsImageRendererFormatRangeStandard;
40
+ } else {
41
+ // Fallback on earlier versions
42
+ format.prefersExtendedRange = false;
43
+ }
44
+
36
45
  UIGraphicsImageRenderer *renderer =
37
46
  [[UIGraphicsImageRenderer alloc] initWithSize:size format:format];
38
47
 
@@ -68,9 +77,12 @@
68
77
  (void *)dataRef);
69
78
 
70
79
  // Make SkImageInfo
80
+ // We're using kBGRA_8888_SkColorType since this is what we get when the
81
+ // UIGraphicsImageRenderer uses the standard format (the extended is using
82
+ // 64bits so it is not suitable for us).
71
83
  SkImageInfo info =
72
84
  SkImageInfo::Make(static_cast<int>(width), static_cast<int>(height),
73
- kRGBA_8888_SkColorType, kPremul_SkAlphaType);
85
+ kBGRA_8888_SkColorType, kPremul_SkAlphaType);
74
86
 
75
87
  // ... and then create the SkImage itself!
76
88
  return SkImage::MakeRasterData(info, skData, bytesPerRow);
@@ -1,3 +1,3 @@
1
1
  import type { Color } from "../../skia";
2
- export declare const interpolateColors: (value: number, inputRange: number[], _outputRange: Color[]) => Float32Array;
2
+ export declare const interpolateColors: (value: number, inputRange: number[], _outputRange: Color[]) => number[];
3
3
  export declare const mixColors: (value: number, x: Color, y: Color) => Float32Array;
@@ -17,8 +17,9 @@ const interpolateColorsRGB = (value, inputRange, outputRange) => {
17
17
  const r = (0, _interpolate.interpolate)(value, inputRange, outputRange.map(c => c[0]), "clamp");
18
18
  const g = (0, _interpolate.interpolate)(value, inputRange, outputRange.map(c => c[1]), "clamp");
19
19
  const b = (0, _interpolate.interpolate)(value, inputRange, outputRange.map(c => c[2]), "clamp");
20
- const a = (0, _interpolate.interpolate)(value, inputRange, outputRange.map(c => c[3]), "clamp");
21
- return new Float32Array([r, g, b, a]);
20
+ const a = (0, _interpolate.interpolate)(value, inputRange, outputRange.map(c => c[3]), "clamp"); // TODO: once Float32Array are supported in the reanimated integration we can switch there
21
+
22
+ return [r, g, b, a];
22
23
  };
23
24
 
24
25
  const interpolateColors = (value, inputRange, _outputRange) => {
@@ -1 +1 @@
1
- {"version":3,"names":["interpolateColorsRGB","value","inputRange","outputRange","r","interpolate","map","c","g","b","a","Float32Array","interpolateColors","_outputRange","cl","Skia","Color","mixColors","x","y","c1","c2","mix"],"sources":["interpolateColors.ts"],"sourcesContent":["import { mix } from \"../../renderer/processors/math\";\nimport type { Color, SkColor } from \"../../skia\";\nimport { Skia } from \"../../skia\";\n\nimport { interpolate } from \"./interpolate\";\n\nconst interpolateColorsRGB = (\n value: number,\n inputRange: number[],\n outputRange: SkColor[]\n) => {\n \"worklet\";\n const r = interpolate(\n value,\n inputRange,\n outputRange.map((c) => c[0]),\n \"clamp\"\n );\n const g = interpolate(\n value,\n inputRange,\n outputRange.map((c) => c[1]),\n \"clamp\"\n );\n const b = interpolate(\n value,\n inputRange,\n outputRange.map((c) => c[2]),\n \"clamp\"\n );\n const a = interpolate(\n value,\n inputRange,\n outputRange.map((c) => c[3]),\n \"clamp\"\n );\n return new Float32Array([r, g, b, a]);\n};\n\nexport const interpolateColors = (\n value: number,\n inputRange: number[],\n _outputRange: Color[]\n) => {\n \"worklet\";\n const outputRange = _outputRange.map((cl) => Skia.Color(cl));\n return interpolateColorsRGB(value, inputRange, outputRange);\n};\n\nexport const mixColors = (value: number, x: Color, y: Color) => {\n \"worklet\";\n const c1 = Skia.Color(x);\n const c2 = Skia.Color(y);\n return new Float32Array([\n mix(value, c1[0], c2[0]),\n mix(value, c1[1], c2[1]),\n mix(value, c1[2], c2[2]),\n mix(value, c1[3], c2[3]),\n ]);\n};\n"],"mappings":";;;;;;;AAAA;;AAEA;;AAEA;;AAEA,MAAMA,oBAAoB,GAAG,CAC3BC,KAD2B,EAE3BC,UAF2B,EAG3BC,WAH2B,KAIxB;EACH;;EACA,MAAMC,CAAC,GAAG,IAAAC,wBAAA,EACRJ,KADQ,EAERC,UAFQ,EAGRC,WAAW,CAACG,GAAZ,CAAiBC,CAAD,IAAOA,CAAC,CAAC,CAAD,CAAxB,CAHQ,EAIR,OAJQ,CAAV;EAMA,MAAMC,CAAC,GAAG,IAAAH,wBAAA,EACRJ,KADQ,EAERC,UAFQ,EAGRC,WAAW,CAACG,GAAZ,CAAiBC,CAAD,IAAOA,CAAC,CAAC,CAAD,CAAxB,CAHQ,EAIR,OAJQ,CAAV;EAMA,MAAME,CAAC,GAAG,IAAAJ,wBAAA,EACRJ,KADQ,EAERC,UAFQ,EAGRC,WAAW,CAACG,GAAZ,CAAiBC,CAAD,IAAOA,CAAC,CAAC,CAAD,CAAxB,CAHQ,EAIR,OAJQ,CAAV;EAMA,MAAMG,CAAC,GAAG,IAAAL,wBAAA,EACRJ,KADQ,EAERC,UAFQ,EAGRC,WAAW,CAACG,GAAZ,CAAiBC,CAAD,IAAOA,CAAC,CAAC,CAAD,CAAxB,CAHQ,EAIR,OAJQ,CAAV;EAMA,OAAO,IAAII,YAAJ,CAAiB,CAACP,CAAD,EAAII,CAAJ,EAAOC,CAAP,EAAUC,CAAV,CAAjB,CAAP;AACD,CA/BD;;AAiCO,MAAME,iBAAiB,GAAG,CAC/BX,KAD+B,EAE/BC,UAF+B,EAG/BW,YAH+B,KAI5B;EACH;;EACA,MAAMV,WAAW,GAAGU,YAAY,CAACP,GAAb,CAAkBQ,EAAD,IAAQC,UAAA,CAAKC,KAAL,CAAWF,EAAX,CAAzB,CAApB;;EACA,OAAOd,oBAAoB,CAACC,KAAD,EAAQC,UAAR,EAAoBC,WAApB,CAA3B;AACD,CARM;;;;AAUA,MAAMc,SAAS,GAAG,CAAChB,KAAD,EAAgBiB,CAAhB,EAA0BC,CAA1B,KAAuC;EAC9D;;EACA,MAAMC,EAAE,GAAGL,UAAA,CAAKC,KAAL,CAAWE,CAAX,CAAX;;EACA,MAAMG,EAAE,GAAGN,UAAA,CAAKC,KAAL,CAAWG,CAAX,CAAX;;EACA,OAAO,IAAIR,YAAJ,CAAiB,CACtB,IAAAW,SAAA,EAAIrB,KAAJ,EAAWmB,EAAE,CAAC,CAAD,CAAb,EAAkBC,EAAE,CAAC,CAAD,CAApB,CADsB,EAEtB,IAAAC,SAAA,EAAIrB,KAAJ,EAAWmB,EAAE,CAAC,CAAD,CAAb,EAAkBC,EAAE,CAAC,CAAD,CAApB,CAFsB,EAGtB,IAAAC,SAAA,EAAIrB,KAAJ,EAAWmB,EAAE,CAAC,CAAD,CAAb,EAAkBC,EAAE,CAAC,CAAD,CAApB,CAHsB,EAItB,IAAAC,SAAA,EAAIrB,KAAJ,EAAWmB,EAAE,CAAC,CAAD,CAAb,EAAkBC,EAAE,CAAC,CAAD,CAApB,CAJsB,CAAjB,CAAP;AAMD,CAVM"}
1
+ {"version":3,"names":["interpolateColorsRGB","value","inputRange","outputRange","r","interpolate","map","c","g","b","a","interpolateColors","_outputRange","cl","Skia","Color","mixColors","x","y","c1","c2","Float32Array","mix"],"sources":["interpolateColors.ts"],"sourcesContent":["import { mix } from \"../../renderer/processors/math\";\nimport type { Color, SkColor } from \"../../skia\";\nimport { Skia } from \"../../skia\";\n\nimport { interpolate } from \"./interpolate\";\n\nconst interpolateColorsRGB = (\n value: number,\n inputRange: number[],\n outputRange: SkColor[]\n) => {\n \"worklet\";\n const r = interpolate(\n value,\n inputRange,\n outputRange.map((c) => c[0]),\n \"clamp\"\n );\n const g = interpolate(\n value,\n inputRange,\n outputRange.map((c) => c[1]),\n \"clamp\"\n );\n const b = interpolate(\n value,\n inputRange,\n outputRange.map((c) => c[2]),\n \"clamp\"\n );\n const a = interpolate(\n value,\n inputRange,\n outputRange.map((c) => c[3]),\n \"clamp\"\n );\n // TODO: once Float32Array are supported in the reanimated integration we can switch there\n return [r, g, b, a];\n};\n\nexport const interpolateColors = (\n value: number,\n inputRange: number[],\n _outputRange: Color[]\n) => {\n \"worklet\";\n const outputRange = _outputRange.map((cl) => Skia.Color(cl));\n return interpolateColorsRGB(value, inputRange, outputRange);\n};\n\nexport const mixColors = (value: number, x: Color, y: Color) => {\n \"worklet\";\n const c1 = Skia.Color(x);\n const c2 = Skia.Color(y);\n return new Float32Array([\n mix(value, c1[0], c2[0]),\n mix(value, c1[1], c2[1]),\n mix(value, c1[2], c2[2]),\n mix(value, c1[3], c2[3]),\n ]);\n};\n"],"mappings":";;;;;;;AAAA;;AAEA;;AAEA;;AAEA,MAAMA,oBAAoB,GAAG,CAC3BC,KAD2B,EAE3BC,UAF2B,EAG3BC,WAH2B,KAIxB;EACH;;EACA,MAAMC,CAAC,GAAG,IAAAC,wBAAA,EACRJ,KADQ,EAERC,UAFQ,EAGRC,WAAW,CAACG,GAAZ,CAAiBC,CAAD,IAAOA,CAAC,CAAC,CAAD,CAAxB,CAHQ,EAIR,OAJQ,CAAV;EAMA,MAAMC,CAAC,GAAG,IAAAH,wBAAA,EACRJ,KADQ,EAERC,UAFQ,EAGRC,WAAW,CAACG,GAAZ,CAAiBC,CAAD,IAAOA,CAAC,CAAC,CAAD,CAAxB,CAHQ,EAIR,OAJQ,CAAV;EAMA,MAAME,CAAC,GAAG,IAAAJ,wBAAA,EACRJ,KADQ,EAERC,UAFQ,EAGRC,WAAW,CAACG,GAAZ,CAAiBC,CAAD,IAAOA,CAAC,CAAC,CAAD,CAAxB,CAHQ,EAIR,OAJQ,CAAV;EAMA,MAAMG,CAAC,GAAG,IAAAL,wBAAA,EACRJ,KADQ,EAERC,UAFQ,EAGRC,WAAW,CAACG,GAAZ,CAAiBC,CAAD,IAAOA,CAAC,CAAC,CAAD,CAAxB,CAHQ,EAIR,OAJQ,CAAV,CApBG,CA0BH;;EACA,OAAO,CAACH,CAAD,EAAII,CAAJ,EAAOC,CAAP,EAAUC,CAAV,CAAP;AACD,CAhCD;;AAkCO,MAAMC,iBAAiB,GAAG,CAC/BV,KAD+B,EAE/BC,UAF+B,EAG/BU,YAH+B,KAI5B;EACH;;EACA,MAAMT,WAAW,GAAGS,YAAY,CAACN,GAAb,CAAkBO,EAAD,IAAQC,UAAA,CAAKC,KAAL,CAAWF,EAAX,CAAzB,CAApB;;EACA,OAAOb,oBAAoB,CAACC,KAAD,EAAQC,UAAR,EAAoBC,WAApB,CAA3B;AACD,CARM;;;;AAUA,MAAMa,SAAS,GAAG,CAACf,KAAD,EAAgBgB,CAAhB,EAA0BC,CAA1B,KAAuC;EAC9D;;EACA,MAAMC,EAAE,GAAGL,UAAA,CAAKC,KAAL,CAAWE,CAAX,CAAX;;EACA,MAAMG,EAAE,GAAGN,UAAA,CAAKC,KAAL,CAAWG,CAAX,CAAX;;EACA,OAAO,IAAIG,YAAJ,CAAiB,CACtB,IAAAC,SAAA,EAAIrB,KAAJ,EAAWkB,EAAE,CAAC,CAAD,CAAb,EAAkBC,EAAE,CAAC,CAAD,CAApB,CADsB,EAEtB,IAAAE,SAAA,EAAIrB,KAAJ,EAAWkB,EAAE,CAAC,CAAD,CAAb,EAAkBC,EAAE,CAAC,CAAD,CAApB,CAFsB,EAGtB,IAAAE,SAAA,EAAIrB,KAAJ,EAAWkB,EAAE,CAAC,CAAD,CAAb,EAAkBC,EAAE,CAAC,CAAD,CAApB,CAHsB,EAItB,IAAAE,SAAA,EAAIrB,KAAJ,EAAWkB,EAAE,CAAC,CAAD,CAAb,EAAkBC,EAAE,CAAC,CAAD,CAApB,CAJsB,CAAjB,CAAP;AAMD,CAVM"}
@@ -1,2 +1,2 @@
1
1
  export declare type SkColor = Float32Array;
2
- export declare type Color = string | Float32Array | number;
2
+ export declare type Color = string | Float32Array | number | number[];
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["Color.ts"],"sourcesContent":["// This is the JSI color\nexport type SkColor = Float32Array;\n// Input colors can be string, number or Float32Array\nexport type Color = string | Float32Array | number;\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["Color.ts"],"sourcesContent":["// This is the JSI color\nexport type SkColor = Float32Array;\n// Input colors can be string, number or Float32Array\nexport type Color = string | Float32Array | number | number[];\n"],"mappings":""}
@@ -13,12 +13,12 @@ export declare enum MatrixIndex {
13
13
  }
14
14
  export declare const isMatrix: (obj: unknown) => obj is SkMatrix;
15
15
  export interface SkMatrix extends SkJSIInstance<"Matrix"> {
16
- concat: (matrix: SkMatrix) => void;
17
- translate: (x: number, y: number) => void;
18
- scale: (x: number, y?: number) => void;
19
- skew: (x: number, y: number) => void;
20
- rotate: (theta: number) => void;
21
- identity: () => void;
16
+ concat: (matrix: SkMatrix) => SkMatrix;
17
+ translate: (x: number, y: number) => SkMatrix;
18
+ scale: (x: number, y?: number) => SkMatrix;
19
+ skew: (x: number, y: number) => SkMatrix;
20
+ rotate: (theta: number) => SkMatrix;
21
+ identity: () => SkMatrix;
22
22
  get: () => number[];
23
23
  }
24
24
  declare type Transform2dName = "translateX" | "translateY" | "scale" | "skewX" | "skewY" | "scaleX" | "scaleY" | "rotateZ" | "rotate";
@@ -1 +1 @@
1
- {"version":3,"names":["MatrixIndex","isMatrix","obj","__typename__","processTransform","m","transforms","transform","key","Object","keys","value","translate","scale","skew","rotate","toDegrees","exhaustiveCheck","a","Error","rad","Math","PI"],"sources":["Matrix.ts"],"sourcesContent":["import type { SkJSIInstance } from \"./JsiInstance\";\nimport type { SkCanvas } from \"./Canvas\";\nexport enum MatrixIndex {\n ScaleX = 0,\n SkewX = 1,\n TransX = 2,\n SkewY = 3,\n ScaleY = 4,\n TransY = 5,\n Persp0 = 6,\n Persp1 = 7,\n Persp2 = 8,\n}\n\nexport const isMatrix = (obj: unknown): obj is SkMatrix =>\n obj !== null && (obj as SkJSIInstance<string>).__typename__ === \"Matrix\";\n\nexport interface SkMatrix extends SkJSIInstance<\"Matrix\"> {\n concat: (matrix: SkMatrix) => void;\n translate: (x: number, y: number) => void;\n scale: (x: number, y?: number) => void;\n skew: (x: number, y: number) => void;\n rotate: (theta: number) => void;\n identity: () => void;\n get: () => number[];\n}\n\ntype Transform2dName =\n | \"translateX\"\n | \"translateY\"\n | \"scale\"\n | \"skewX\"\n | \"skewY\"\n | \"scaleX\"\n | \"scaleY\"\n | \"rotateZ\"\n | \"rotate\";\n\ntype Transformations = {\n readonly [Name in Transform2dName]: number;\n};\n\nexport type Transforms2d = readonly (\n | Pick<Transformations, \"translateX\">\n | Pick<Transformations, \"translateY\">\n | Pick<Transformations, \"scale\">\n | Pick<Transformations, \"scaleX\">\n | Pick<Transformations, \"scaleY\">\n | Pick<Transformations, \"skewX\">\n | Pick<Transformations, \"skewY\">\n | Pick<Transformations, \"rotate\">\n)[];\n\nexport interface TransformProp {\n transform?: Transforms2d;\n}\n\nexport const processTransform = <T extends SkMatrix | SkCanvas>(\n m: T,\n transforms: Transforms2d\n) => {\n for (const transform of transforms) {\n const key = Object.keys(transform)[0] as Transform2dName;\n const value = (transform as Pick<Transformations, typeof key>)[key];\n if (key === \"translateX\") {\n m.translate(value, 0);\n continue;\n }\n if (key === \"translateY\") {\n m.translate(0, value);\n continue;\n }\n if (key === \"scale\") {\n m.scale(value, value);\n continue;\n }\n if (key === \"scaleX\") {\n m.scale(value, 1);\n continue;\n }\n if (key === \"scaleY\") {\n m.scale(1, value);\n continue;\n }\n if (key === \"skewX\") {\n m.skew(value, 0);\n continue;\n }\n if (key === \"skewY\") {\n m.skew(0, value);\n continue;\n }\n if (key === \"rotate\" || key === \"rotateZ\") {\n if (isMatrix(m)) {\n m.rotate(value);\n } else {\n m.rotate(toDegrees(value), 0, 0);\n }\n continue;\n }\n exhaustiveCheck(key);\n }\n return m;\n};\n\nconst exhaustiveCheck = (a: never): never => {\n throw new Error(`Unknown transformation: ${a}`);\n};\n\nexport const toDegrees = (rad: number) => {\n return (rad * 180) / Math.PI;\n};\n"],"mappings":";;;;;;IAEYA,W;;;WAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;GAAAA,W,2BAAAA,W;;AAYL,MAAMC,QAAQ,GAAIC,GAAD,IACtBA,GAAG,KAAK,IAAR,IAAiBA,GAAD,CAA+BC,YAA/B,KAAgD,QAD3D;;;;AA2CA,MAAMC,gBAAgB,GAAG,CAC9BC,CAD8B,EAE9BC,UAF8B,KAG3B;EACH,KAAK,MAAMC,SAAX,IAAwBD,UAAxB,EAAoC;IAClC,MAAME,GAAG,GAAGC,MAAM,CAACC,IAAP,CAAYH,SAAZ,EAAuB,CAAvB,CAAZ;IACA,MAAMI,KAAK,GAAIJ,SAAD,CAAiDC,GAAjD,CAAd;;IACA,IAAIA,GAAG,KAAK,YAAZ,EAA0B;MACxBH,CAAC,CAACO,SAAF,CAAYD,KAAZ,EAAmB,CAAnB;MACA;IACD;;IACD,IAAIH,GAAG,KAAK,YAAZ,EAA0B;MACxBH,CAAC,CAACO,SAAF,CAAY,CAAZ,EAAeD,KAAf;MACA;IACD;;IACD,IAAIH,GAAG,KAAK,OAAZ,EAAqB;MACnBH,CAAC,CAACQ,KAAF,CAAQF,KAAR,EAAeA,KAAf;MACA;IACD;;IACD,IAAIH,GAAG,KAAK,QAAZ,EAAsB;MACpBH,CAAC,CAACQ,KAAF,CAAQF,KAAR,EAAe,CAAf;MACA;IACD;;IACD,IAAIH,GAAG,KAAK,QAAZ,EAAsB;MACpBH,CAAC,CAACQ,KAAF,CAAQ,CAAR,EAAWF,KAAX;MACA;IACD;;IACD,IAAIH,GAAG,KAAK,OAAZ,EAAqB;MACnBH,CAAC,CAACS,IAAF,CAAOH,KAAP,EAAc,CAAd;MACA;IACD;;IACD,IAAIH,GAAG,KAAK,OAAZ,EAAqB;MACnBH,CAAC,CAACS,IAAF,CAAO,CAAP,EAAUH,KAAV;MACA;IACD;;IACD,IAAIH,GAAG,KAAK,QAAR,IAAoBA,GAAG,KAAK,SAAhC,EAA2C;MACzC,IAAIP,QAAQ,CAACI,CAAD,CAAZ,EAAiB;QACfA,CAAC,CAACU,MAAF,CAASJ,KAAT;MACD,CAFD,MAEO;QACLN,CAAC,CAACU,MAAF,CAASC,SAAS,CAACL,KAAD,CAAlB,EAA2B,CAA3B,EAA8B,CAA9B;MACD;;MACD;IACD;;IACDM,eAAe,CAACT,GAAD,CAAf;EACD;;EACD,OAAOH,CAAP;AACD,CA9CM;;;;AAgDP,MAAMY,eAAe,GAAIC,CAAD,IAAqB;EAC3C,MAAM,IAAIC,KAAJ,CAAW,2BAA0BD,CAAE,EAAvC,CAAN;AACD,CAFD;;AAIO,MAAMF,SAAS,GAAII,GAAD,IAAiB;EACxC,OAAQA,GAAG,GAAG,GAAP,GAAcC,IAAI,CAACC,EAA1B;AACD,CAFM"}
1
+ {"version":3,"names":["MatrixIndex","isMatrix","obj","__typename__","processTransform","m","transforms","transform","key","Object","keys","value","translate","scale","skew","rotate","toDegrees","exhaustiveCheck","a","Error","rad","Math","PI"],"sources":["Matrix.ts"],"sourcesContent":["import type { SkJSIInstance } from \"./JsiInstance\";\nimport type { SkCanvas } from \"./Canvas\";\nexport enum MatrixIndex {\n ScaleX = 0,\n SkewX = 1,\n TransX = 2,\n SkewY = 3,\n ScaleY = 4,\n TransY = 5,\n Persp0 = 6,\n Persp1 = 7,\n Persp2 = 8,\n}\n\nexport const isMatrix = (obj: unknown): obj is SkMatrix =>\n obj !== null && (obj as SkJSIInstance<string>).__typename__ === \"Matrix\";\n\nexport interface SkMatrix extends SkJSIInstance<\"Matrix\"> {\n concat: (matrix: SkMatrix) => SkMatrix;\n translate: (x: number, y: number) => SkMatrix;\n scale: (x: number, y?: number) => SkMatrix;\n skew: (x: number, y: number) => SkMatrix;\n rotate: (theta: number) => SkMatrix;\n identity: () => SkMatrix;\n get: () => number[];\n}\n\ntype Transform2dName =\n | \"translateX\"\n | \"translateY\"\n | \"scale\"\n | \"skewX\"\n | \"skewY\"\n | \"scaleX\"\n | \"scaleY\"\n | \"rotateZ\"\n | \"rotate\";\n\ntype Transformations = {\n readonly [Name in Transform2dName]: number;\n};\n\nexport type Transforms2d = readonly (\n | Pick<Transformations, \"translateX\">\n | Pick<Transformations, \"translateY\">\n | Pick<Transformations, \"scale\">\n | Pick<Transformations, \"scaleX\">\n | Pick<Transformations, \"scaleY\">\n | Pick<Transformations, \"skewX\">\n | Pick<Transformations, \"skewY\">\n | Pick<Transformations, \"rotate\">\n)[];\n\nexport interface TransformProp {\n transform?: Transforms2d;\n}\n\nexport const processTransform = <T extends SkMatrix | SkCanvas>(\n m: T,\n transforms: Transforms2d\n) => {\n for (const transform of transforms) {\n const key = Object.keys(transform)[0] as Transform2dName;\n const value = (transform as Pick<Transformations, typeof key>)[key];\n if (key === \"translateX\") {\n m.translate(value, 0);\n continue;\n }\n if (key === \"translateY\") {\n m.translate(0, value);\n continue;\n }\n if (key === \"scale\") {\n m.scale(value, value);\n continue;\n }\n if (key === \"scaleX\") {\n m.scale(value, 1);\n continue;\n }\n if (key === \"scaleY\") {\n m.scale(1, value);\n continue;\n }\n if (key === \"skewX\") {\n m.skew(value, 0);\n continue;\n }\n if (key === \"skewY\") {\n m.skew(0, value);\n continue;\n }\n if (key === \"rotate\" || key === \"rotateZ\") {\n if (isMatrix(m)) {\n m.rotate(value);\n } else {\n m.rotate(toDegrees(value), 0, 0);\n }\n continue;\n }\n exhaustiveCheck(key);\n }\n return m;\n};\n\nconst exhaustiveCheck = (a: never): never => {\n throw new Error(`Unknown transformation: ${a}`);\n};\n\nexport const toDegrees = (rad: number) => {\n return (rad * 180) / Math.PI;\n};\n"],"mappings":";;;;;;IAEYA,W;;;WAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;EAAAA,W,CAAAA,W;GAAAA,W,2BAAAA,W;;AAYL,MAAMC,QAAQ,GAAIC,GAAD,IACtBA,GAAG,KAAK,IAAR,IAAiBA,GAAD,CAA+BC,YAA/B,KAAgD,QAD3D;;;;AA2CA,MAAMC,gBAAgB,GAAG,CAC9BC,CAD8B,EAE9BC,UAF8B,KAG3B;EACH,KAAK,MAAMC,SAAX,IAAwBD,UAAxB,EAAoC;IAClC,MAAME,GAAG,GAAGC,MAAM,CAACC,IAAP,CAAYH,SAAZ,EAAuB,CAAvB,CAAZ;IACA,MAAMI,KAAK,GAAIJ,SAAD,CAAiDC,GAAjD,CAAd;;IACA,IAAIA,GAAG,KAAK,YAAZ,EAA0B;MACxBH,CAAC,CAACO,SAAF,CAAYD,KAAZ,EAAmB,CAAnB;MACA;IACD;;IACD,IAAIH,GAAG,KAAK,YAAZ,EAA0B;MACxBH,CAAC,CAACO,SAAF,CAAY,CAAZ,EAAeD,KAAf;MACA;IACD;;IACD,IAAIH,GAAG,KAAK,OAAZ,EAAqB;MACnBH,CAAC,CAACQ,KAAF,CAAQF,KAAR,EAAeA,KAAf;MACA;IACD;;IACD,IAAIH,GAAG,KAAK,QAAZ,EAAsB;MACpBH,CAAC,CAACQ,KAAF,CAAQF,KAAR,EAAe,CAAf;MACA;IACD;;IACD,IAAIH,GAAG,KAAK,QAAZ,EAAsB;MACpBH,CAAC,CAACQ,KAAF,CAAQ,CAAR,EAAWF,KAAX;MACA;IACD;;IACD,IAAIH,GAAG,KAAK,OAAZ,EAAqB;MACnBH,CAAC,CAACS,IAAF,CAAOH,KAAP,EAAc,CAAd;MACA;IACD;;IACD,IAAIH,GAAG,KAAK,OAAZ,EAAqB;MACnBH,CAAC,CAACS,IAAF,CAAO,CAAP,EAAUH,KAAV;MACA;IACD;;IACD,IAAIH,GAAG,KAAK,QAAR,IAAoBA,GAAG,KAAK,SAAhC,EAA2C;MACzC,IAAIP,QAAQ,CAACI,CAAD,CAAZ,EAAiB;QACfA,CAAC,CAACU,MAAF,CAASJ,KAAT;MACD,CAFD,MAEO;QACLN,CAAC,CAACU,MAAF,CAASC,SAAS,CAACL,KAAD,CAAlB,EAA2B,CAA3B,EAA8B,CAA9B;MACD;;MACD;IACD;;IACDM,eAAe,CAACT,GAAD,CAAf;EACD;;EACD,OAAOH,CAAP;AACD,CA9CM;;;;AAgDP,MAAMY,eAAe,GAAIC,CAAD,IAAqB;EAC3C,MAAM,IAAIC,KAAJ,CAAW,2BAA0BD,CAAE,EAAvC,CAAN;AACD,CAFD;;AAIO,MAAMF,SAAS,GAAII,GAAD,IAAiB;EACxC,OAAQA,GAAG,GAAG,GAAP,GAAcC,IAAI,CAACC,EAA1B;AACD,CAFM"}
@@ -334,6 +334,8 @@ const parseCSSColor = cssStr => {
334
334
  const Color = color => {
335
335
  if (color instanceof Float32Array) {
336
336
  return color;
337
+ } else if (Array.isArray(color)) {
338
+ return new Float32Array(color);
337
339
  } else if (typeof color === "string") {
338
340
  const r = parseCSSColor(color);
339
341
  const rgba = r === null ? CSSColorTable.black : r;