@shopify/react-native-skia 2.0.7 → 2.1.0

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 (283) hide show
  1. package/android/CMakeLists.txt +20 -1
  2. package/cpp/api/JsiSkApi.h +3 -0
  3. package/cpp/api/JsiSkImageFilterFactory.h +478 -39
  4. package/cpp/api/JsiSkSkottie.h +590 -0
  5. package/cpp/api/JsiSkottieFactory.h +65 -0
  6. package/cpp/api/recorder/Command.h +1 -0
  7. package/cpp/api/recorder/Convertor.h +16 -0
  8. package/cpp/api/recorder/Drawings.h +23 -0
  9. package/cpp/api/recorder/JsiRecorder.h +6 -0
  10. package/cpp/api/recorder/RNRecorder.h +9 -0
  11. package/cpp/api/third_party/SkottieUtils.cpp +333 -0
  12. package/cpp/api/third_party/SkottieUtils.h +172 -0
  13. package/cpp/skia/modules/jsonreader/SkJSONReader.cpp +980 -0
  14. package/cpp/skia/modules/jsonreader/SkJSONReader.h +389 -0
  15. package/cpp/skia/modules/skottie/include/ExternalLayer.h +56 -0
  16. package/cpp/skia/modules/skottie/include/Skottie.h +313 -0
  17. package/cpp/skia/modules/skottie/include/SkottieProperty.h +190 -0
  18. package/cpp/skia/modules/skottie/include/SlotManager.h +113 -0
  19. package/cpp/skia/modules/skottie/include/TextShaper.h +200 -0
  20. package/cpp/skia/modules/skottie/src/SkottieValue.h +56 -0
  21. package/cpp/skia/modules/skottie/src/animator/Animator.h +89 -0
  22. package/cpp/skia/modules/skottie/src/text/Font.h +82 -0
  23. package/cpp/skia/modules/skottie/src/text/TextAdapter.h +155 -0
  24. package/cpp/skia/modules/skottie/src/text/TextAnimator.h +121 -0
  25. package/cpp/skia/modules/skottie/src/text/TextValue.h +28 -0
  26. package/cpp/skia/modules/sksg/include/SkSGClipEffect.h +61 -0
  27. package/cpp/skia/modules/sksg/include/SkSGColorFilter.h +135 -0
  28. package/cpp/skia/modules/sksg/include/SkSGDraw.h +57 -0
  29. package/cpp/skia/modules/sksg/include/SkSGEffectNode.h +50 -0
  30. package/cpp/skia/modules/sksg/include/SkSGGeometryEffect.h +181 -0
  31. package/cpp/skia/modules/sksg/include/SkSGGeometryNode.h +54 -0
  32. package/cpp/skia/modules/sksg/include/SkSGGradient.h +108 -0
  33. package/cpp/skia/modules/sksg/include/SkSGGroup.h +65 -0
  34. package/cpp/skia/modules/sksg/include/SkSGImage.h +59 -0
  35. package/cpp/skia/modules/sksg/include/SkSGInvalidationController.h +46 -0
  36. package/cpp/skia/modules/sksg/include/SkSGMaskEffect.h +65 -0
  37. package/cpp/skia/modules/sksg/include/SkSGMerge.h +74 -0
  38. package/cpp/skia/modules/sksg/include/SkSGNode.h +128 -0
  39. package/cpp/skia/modules/sksg/include/SkSGOpacityEffect.h +54 -0
  40. package/cpp/skia/modules/sksg/include/SkSGPaint.h +112 -0
  41. package/cpp/skia/modules/sksg/include/SkSGPath.h +68 -0
  42. package/cpp/skia/modules/sksg/include/SkSGPlane.h +47 -0
  43. package/cpp/skia/modules/sksg/include/SkSGRect.h +122 -0
  44. package/cpp/skia/modules/sksg/include/SkSGRenderEffect.h +283 -0
  45. package/cpp/skia/modules/sksg/include/SkSGRenderNode.h +157 -0
  46. package/cpp/skia/modules/sksg/include/SkSGScene.h +47 -0
  47. package/cpp/skia/modules/sksg/include/SkSGText.h +82 -0
  48. package/cpp/skia/modules/sksg/include/SkSGTransform.h +127 -0
  49. package/cpp/skia/src/base/SkArenaAlloc.h +371 -0
  50. package/lib/commonjs/dom/nodes/datatypes/Gradient.d.ts +15 -15
  51. package/lib/commonjs/dom/types/Drawings.d.ts +5 -1
  52. package/lib/commonjs/dom/types/Drawings.js.map +1 -1
  53. package/lib/commonjs/dom/types/NodeType.d.ts +2 -1
  54. package/lib/commonjs/dom/types/NodeType.js +2 -0
  55. package/lib/commonjs/dom/types/NodeType.js.map +1 -1
  56. package/lib/commonjs/renderer/__tests__/e2e/AdvancedImageFilters.spec.d.ts +1 -0
  57. package/lib/commonjs/renderer/__tests__/e2e/Camera.spec.d.ts +21 -0
  58. package/lib/commonjs/renderer/__tests__/e2e/LightingImageFilters.spec.d.ts +1 -0
  59. package/lib/commonjs/renderer/__tests__/e2e/Skottie.spec.d.ts +1 -0
  60. package/lib/commonjs/renderer/__tests__/setup.d.ts +5 -0
  61. package/lib/commonjs/renderer/components/Skottie.d.ts +4 -0
  62. package/lib/commonjs/renderer/components/Skottie.js +13 -0
  63. package/lib/commonjs/renderer/components/Skottie.js.map +1 -0
  64. package/lib/commonjs/renderer/components/index.d.ts +1 -0
  65. package/lib/commonjs/renderer/components/index.js +11 -0
  66. package/lib/commonjs/renderer/components/index.js.map +1 -1
  67. package/lib/commonjs/skia/types/ImageFilter/ImageFilterFactory.d.ts +252 -15
  68. package/lib/commonjs/skia/types/ImageFilter/ImageFilterFactory.js.map +1 -1
  69. package/lib/commonjs/skia/types/Matrix4.d.ts +11 -2
  70. package/lib/commonjs/skia/types/Matrix4.js +42 -1
  71. package/lib/commonjs/skia/types/Matrix4.js.map +1 -1
  72. package/lib/commonjs/skia/types/Recorder.d.ts +2 -1
  73. package/lib/commonjs/skia/types/Recorder.js.map +1 -1
  74. package/lib/commonjs/skia/types/Skia.d.ts +2 -0
  75. package/lib/commonjs/skia/types/Skia.js.map +1 -1
  76. package/lib/commonjs/skia/types/Skottie.d.ts +223 -0
  77. package/lib/commonjs/skia/types/Skottie.js +73 -0
  78. package/lib/commonjs/skia/types/Skottie.js.map +1 -0
  79. package/lib/commonjs/skia/types/index.d.ts +1 -0
  80. package/lib/commonjs/skia/types/index.js +11 -0
  81. package/lib/commonjs/skia/types/index.js.map +1 -1
  82. package/lib/commonjs/skia/web/JsiSkImageFilterFactory.d.ts +29 -12
  83. package/lib/commonjs/skia/web/JsiSkImageFilterFactory.js +88 -19
  84. package/lib/commonjs/skia/web/JsiSkImageFilterFactory.js.map +1 -1
  85. package/lib/commonjs/skia/web/JsiSkia.js +2 -0
  86. package/lib/commonjs/skia/web/JsiSkia.js.map +1 -1
  87. package/lib/commonjs/skia/web/JsiSkottieAnimation.d.ts +59 -0
  88. package/lib/commonjs/skia/web/JsiSkottieAnimation.js +243 -0
  89. package/lib/commonjs/skia/web/JsiSkottieAnimation.js.map +1 -0
  90. package/lib/commonjs/skia/web/JsiSkottieFactory.d.ts +9 -0
  91. package/lib/commonjs/skia/web/JsiSkottieFactory.js +26 -0
  92. package/lib/commonjs/skia/web/JsiSkottieFactory.js.map +1 -0
  93. package/lib/commonjs/sksg/Elements.d.ts +2 -1
  94. package/lib/commonjs/sksg/Elements.js.map +1 -1
  95. package/lib/commonjs/sksg/Recorder/Core.d.ts +4 -2
  96. package/lib/commonjs/sksg/Recorder/Core.js +1 -0
  97. package/lib/commonjs/sksg/Recorder/Core.js.map +1 -1
  98. package/lib/commonjs/sksg/Recorder/Player.js +2 -0
  99. package/lib/commonjs/sksg/Recorder/Player.js.map +1 -1
  100. package/lib/commonjs/sksg/Recorder/ReanimatedRecorder.d.ts +2 -1
  101. package/lib/commonjs/sksg/Recorder/ReanimatedRecorder.js +4 -0
  102. package/lib/commonjs/sksg/Recorder/ReanimatedRecorder.js.map +1 -1
  103. package/lib/commonjs/sksg/Recorder/Recorder.d.ts +2 -1
  104. package/lib/commonjs/sksg/Recorder/Recorder.js +6 -0
  105. package/lib/commonjs/sksg/Recorder/Recorder.js.map +1 -1
  106. package/lib/commonjs/sksg/Recorder/Visitor.js +3 -0
  107. package/lib/commonjs/sksg/Recorder/Visitor.js.map +1 -1
  108. package/lib/commonjs/sksg/Recorder/commands/Drawing.d.ts +2 -2
  109. package/lib/commonjs/sksg/Recorder/commands/Drawing.js +11 -4
  110. package/lib/commonjs/sksg/Recorder/commands/Drawing.js.map +1 -1
  111. package/lib/commonjs/sksg/Recorder/commands/ImageFilters.js +1 -1
  112. package/lib/commonjs/sksg/Recorder/commands/ImageFilters.js.map +1 -1
  113. package/lib/module/dom/nodes/datatypes/Gradient.d.ts +15 -15
  114. package/lib/module/dom/types/Drawings.d.ts +5 -1
  115. package/lib/module/dom/types/Drawings.js.map +1 -1
  116. package/lib/module/dom/types/NodeType.d.ts +2 -1
  117. package/lib/module/dom/types/NodeType.js +2 -0
  118. package/lib/module/dom/types/NodeType.js.map +1 -1
  119. package/lib/module/renderer/__tests__/e2e/AdvancedImageFilters.spec.d.ts +1 -0
  120. package/lib/module/renderer/__tests__/e2e/Camera.spec.d.ts +21 -0
  121. package/lib/module/renderer/__tests__/e2e/LightingImageFilters.spec.d.ts +1 -0
  122. package/lib/module/renderer/__tests__/e2e/Skottie.spec.d.ts +1 -0
  123. package/lib/module/renderer/__tests__/setup.d.ts +5 -0
  124. package/lib/module/renderer/components/Skottie.d.ts +4 -0
  125. package/lib/module/renderer/components/Skottie.js +5 -0
  126. package/lib/module/renderer/components/Skottie.js.map +1 -0
  127. package/lib/module/renderer/components/index.d.ts +1 -0
  128. package/lib/module/renderer/components/index.js +1 -0
  129. package/lib/module/renderer/components/index.js.map +1 -1
  130. package/lib/module/skia/types/ImageFilter/ImageFilterFactory.d.ts +252 -15
  131. package/lib/module/skia/types/ImageFilter/ImageFilterFactory.js.map +1 -1
  132. package/lib/module/skia/types/Matrix4.d.ts +11 -2
  133. package/lib/module/skia/types/Matrix4.js +40 -0
  134. package/lib/module/skia/types/Matrix4.js.map +1 -1
  135. package/lib/module/skia/types/Recorder.d.ts +2 -1
  136. package/lib/module/skia/types/Recorder.js.map +1 -1
  137. package/lib/module/skia/types/Skia.d.ts +2 -0
  138. package/lib/module/skia/types/Skia.js.map +1 -1
  139. package/lib/module/skia/types/Skottie.d.ts +223 -0
  140. package/lib/module/skia/types/Skottie.js +74 -0
  141. package/lib/module/skia/types/Skottie.js.map +1 -0
  142. package/lib/module/skia/types/index.d.ts +1 -0
  143. package/lib/module/skia/types/index.js +1 -0
  144. package/lib/module/skia/types/index.js.map +1 -1
  145. package/lib/module/skia/web/JsiSkImageFilterFactory.d.ts +29 -12
  146. package/lib/module/skia/web/JsiSkImageFilterFactory.js +88 -19
  147. package/lib/module/skia/web/JsiSkImageFilterFactory.js.map +1 -1
  148. package/lib/module/skia/web/JsiSkia.js +2 -0
  149. package/lib/module/skia/web/JsiSkia.js.map +1 -1
  150. package/lib/module/skia/web/JsiSkottieAnimation.d.ts +59 -0
  151. package/lib/module/skia/web/JsiSkottieAnimation.js +236 -0
  152. package/lib/module/skia/web/JsiSkottieAnimation.js.map +1 -0
  153. package/lib/module/skia/web/JsiSkottieFactory.d.ts +9 -0
  154. package/lib/module/skia/web/JsiSkottieFactory.js +19 -0
  155. package/lib/module/skia/web/JsiSkottieFactory.js.map +1 -0
  156. package/lib/module/sksg/Elements.d.ts +2 -1
  157. package/lib/module/sksg/Elements.js.map +1 -1
  158. package/lib/module/sksg/Recorder/Core.d.ts +4 -2
  159. package/lib/module/sksg/Recorder/Core.js +1 -0
  160. package/lib/module/sksg/Recorder/Core.js.map +1 -1
  161. package/lib/module/sksg/Recorder/Player.js +3 -1
  162. package/lib/module/sksg/Recorder/Player.js.map +1 -1
  163. package/lib/module/sksg/Recorder/ReanimatedRecorder.d.ts +2 -1
  164. package/lib/module/sksg/Recorder/ReanimatedRecorder.js +4 -0
  165. package/lib/module/sksg/Recorder/ReanimatedRecorder.js.map +1 -1
  166. package/lib/module/sksg/Recorder/Recorder.d.ts +2 -1
  167. package/lib/module/sksg/Recorder/Recorder.js +6 -0
  168. package/lib/module/sksg/Recorder/Recorder.js.map +1 -1
  169. package/lib/module/sksg/Recorder/Visitor.js +3 -0
  170. package/lib/module/sksg/Recorder/Visitor.js.map +1 -1
  171. package/lib/module/sksg/Recorder/commands/Drawing.d.ts +2 -2
  172. package/lib/module/sksg/Recorder/commands/Drawing.js +9 -2
  173. package/lib/module/sksg/Recorder/commands/Drawing.js.map +1 -1
  174. package/lib/module/sksg/Recorder/commands/ImageFilters.js +1 -1
  175. package/lib/module/sksg/Recorder/commands/ImageFilters.js.map +1 -1
  176. package/lib/typescript/lib/commonjs/renderer/components/Skottie.d.ts +2 -0
  177. package/lib/typescript/lib/commonjs/skia/types/Matrix4.d.ts +1 -0
  178. package/lib/typescript/lib/commonjs/skia/types/Skottie.d.ts +6 -0
  179. package/lib/typescript/lib/commonjs/skia/web/JsiSkImageFilterFactory.d.ts +22 -5
  180. package/lib/typescript/lib/commonjs/skia/web/JsiSkia.d.ts +2 -0
  181. package/lib/typescript/lib/commonjs/skia/web/JsiSkottieAnimation.d.ts +48 -0
  182. package/lib/typescript/lib/commonjs/skia/web/JsiSkottieFactory.d.ts +6 -0
  183. package/lib/typescript/lib/commonjs/sksg/Recorder/ReanimatedRecorder.d.ts +1 -0
  184. package/lib/typescript/lib/commonjs/sksg/Recorder/Recorder.d.ts +1 -0
  185. package/lib/typescript/lib/commonjs/sksg/Recorder/commands/Drawing.d.ts +1 -1
  186. package/lib/typescript/lib/module/mock/index.d.ts +7 -0
  187. package/lib/typescript/lib/module/renderer/components/Skottie.d.ts +2 -0
  188. package/lib/typescript/lib/module/renderer/components/index.d.ts +1 -0
  189. package/lib/typescript/lib/module/skia/Skia.web.d.ts +1 -0
  190. package/lib/typescript/lib/module/skia/types/Matrix4.d.ts +1 -0
  191. package/lib/typescript/lib/module/skia/types/Skottie.d.ts +5 -0
  192. package/lib/typescript/lib/module/skia/types/index.d.ts +1 -0
  193. package/lib/typescript/lib/module/skia/web/JsiSkImageFilterFactory.d.ts +22 -5
  194. package/lib/typescript/lib/module/skia/web/JsiSkia.d.ts +2 -0
  195. package/lib/typescript/lib/module/skia/web/JsiSkottieAnimation.d.ts +47 -0
  196. package/lib/typescript/lib/module/skia/web/JsiSkottieFactory.d.ts +5 -0
  197. package/lib/typescript/lib/module/sksg/Recorder/ReanimatedRecorder.d.ts +1 -0
  198. package/lib/typescript/lib/module/sksg/Recorder/Recorder.d.ts +1 -0
  199. package/lib/typescript/lib/module/sksg/Recorder/commands/Drawing.d.ts +1 -1
  200. package/lib/typescript/src/dom/nodes/datatypes/Gradient.d.ts +15 -15
  201. package/lib/typescript/src/dom/types/Drawings.d.ts +5 -1
  202. package/lib/typescript/src/dom/types/NodeType.d.ts +2 -1
  203. package/lib/typescript/src/renderer/__tests__/e2e/AdvancedImageFilters.spec.d.ts +1 -0
  204. package/lib/typescript/src/renderer/__tests__/e2e/Camera.spec.d.ts +21 -0
  205. package/lib/typescript/src/renderer/__tests__/e2e/LightingImageFilters.spec.d.ts +1 -0
  206. package/lib/typescript/src/renderer/__tests__/e2e/Skottie.spec.d.ts +1 -0
  207. package/lib/typescript/src/renderer/__tests__/setup.d.ts +5 -0
  208. package/lib/typescript/src/renderer/components/Skottie.d.ts +4 -0
  209. package/lib/typescript/src/renderer/components/index.d.ts +1 -0
  210. package/lib/typescript/src/skia/types/ImageFilter/ImageFilterFactory.d.ts +252 -15
  211. package/lib/typescript/src/skia/types/Matrix4.d.ts +11 -2
  212. package/lib/typescript/src/skia/types/Recorder.d.ts +2 -1
  213. package/lib/typescript/src/skia/types/Skia.d.ts +2 -0
  214. package/lib/typescript/src/skia/types/Skottie.d.ts +223 -0
  215. package/lib/typescript/src/skia/types/index.d.ts +1 -0
  216. package/lib/typescript/src/skia/web/JsiSkImageFilterFactory.d.ts +29 -12
  217. package/lib/typescript/src/skia/web/JsiSkottieAnimation.d.ts +59 -0
  218. package/lib/typescript/src/skia/web/JsiSkottieFactory.d.ts +9 -0
  219. package/lib/typescript/src/sksg/Elements.d.ts +2 -1
  220. package/lib/typescript/src/sksg/Recorder/Core.d.ts +4 -2
  221. package/lib/typescript/src/sksg/Recorder/ReanimatedRecorder.d.ts +2 -1
  222. package/lib/typescript/src/sksg/Recorder/Recorder.d.ts +2 -1
  223. package/lib/typescript/src/sksg/Recorder/commands/Drawing.d.ts +2 -2
  224. package/libs/android/arm64-v8a/libjsonreader.a +0 -0
  225. package/libs/android/armeabi-v7a/libjsonreader.a +0 -0
  226. package/libs/android/x86/libjsonreader.a +0 -0
  227. package/libs/android/x86_64/libjsonreader.a +0 -0
  228. package/libs/apple/libpathops.xcframework/Info.plist +8 -8
  229. package/libs/apple/libskia.xcframework/Info.plist +14 -14
  230. package/libs/apple/libskottie.xcframework/Info.plist +14 -14
  231. package/libs/apple/libskparagraph.xcframework/Info.plist +16 -16
  232. package/libs/apple/libsksg.xcframework/Info.plist +5 -5
  233. package/libs/apple/libskshaper.xcframework/Info.plist +14 -14
  234. package/libs/apple/libskunicode_libgrapheme.xcframework/Info.plist +14 -14
  235. package/libs/apple/libsvg.xcframework/Info.plist +14 -14
  236. package/package.json +1 -1
  237. package/react-native-skia.podspec +4 -2
  238. package/src/__tests__/snapshots/matrix4/camera-corner.png +0 -0
  239. package/src/__tests__/snapshots/matrix4/camera-offset.png +0 -0
  240. package/src/__tests__/snapshots/matrix4/camera-top-left-center.png +0 -0
  241. package/src/__tests__/snapshots/matrix4/camera-zoom-out.png +0 -0
  242. package/src/__tests__/snapshots/matrix4/full-rect.png +0 -0
  243. package/src/__tests__/snapshots/matrix4/rect.png +0 -0
  244. package/src/__tests__/snapshots/matrix4/scaled-rect.png +0 -0
  245. package/src/__tests__/snapshots/matrix4/test-perspective.png +0 -0
  246. package/src/__tests__/snapshots/matrix4/test-perspective2.png +0 -0
  247. package/src/dom/types/Drawings.ts +6 -0
  248. package/src/dom/types/NodeType.ts +2 -0
  249. package/src/renderer/__tests__/e2e/AdvancedImageFilters.spec.tsx +492 -0
  250. package/src/renderer/__tests__/e2e/Camera.spec.tsx +475 -0
  251. package/src/renderer/__tests__/e2e/LightingImageFilters.spec.tsx +1478 -0
  252. package/src/renderer/__tests__/e2e/Skottie.spec.tsx +440 -0
  253. package/src/renderer/__tests__/e2e/setup/skottie/basic_slots.json +1118 -0
  254. package/src/renderer/__tests__/e2e/setup/skottie/color-props.json +1 -0
  255. package/src/renderer/__tests__/e2e/setup/skottie/confetti.json +5899 -0
  256. package/src/renderer/__tests__/e2e/setup/skottie/drinks.json +43857 -0
  257. package/src/renderer/__tests__/e2e/setup/skottie/fingerprint.json +1 -0
  258. package/src/renderer/__tests__/e2e/setup/skottie/lego_loader.json +29540 -0
  259. package/src/renderer/__tests__/e2e/setup/skottie/new-drop.json +1 -0
  260. package/src/renderer/__tests__/e2e/setup/skottie/onboarding.json +1 -0
  261. package/src/renderer/__tests__/e2e/setup/skottie/text-layer.json +1 -0
  262. package/src/renderer/__tests__/setup.tsx +23 -0
  263. package/src/renderer/components/Skottie.tsx +8 -0
  264. package/src/renderer/components/index.ts +1 -0
  265. package/src/skia/__tests__/assets/Avenir-Heavy.ttf +0 -0
  266. package/src/skia/types/ImageFilter/ImageFilterFactory.ts +391 -21
  267. package/src/skia/types/Matrix4.ts +108 -2
  268. package/src/skia/types/Recorder.ts +2 -0
  269. package/src/skia/types/Skia.ts +2 -0
  270. package/src/skia/types/Skottie.ts +266 -0
  271. package/src/skia/types/index.ts +1 -0
  272. package/src/skia/web/JsiSkImageFilterFactory.ts +266 -31
  273. package/src/skia/web/JsiSkia.ts +2 -0
  274. package/src/skia/web/JsiSkottieAnimation.ts +259 -0
  275. package/src/skia/web/JsiSkottieFactory.ts +25 -0
  276. package/src/sksg/Elements.tsx +2 -0
  277. package/src/sksg/Recorder/Core.ts +3 -0
  278. package/src/sksg/Recorder/Player.ts +3 -0
  279. package/src/sksg/Recorder/ReanimatedRecorder.ts +6 -0
  280. package/src/sksg/Recorder/Recorder.ts +5 -0
  281. package/src/sksg/Recorder/Visitor.ts +3 -0
  282. package/src/sksg/Recorder/commands/Drawing.ts +7 -3
  283. package/src/sksg/Recorder/commands/ImageFilters.ts +1 -1
@@ -0,0 +1,492 @@
1
+ import { docPath, checkImage, itRunsE2eOnly } from "../../../__tests__/setup";
2
+ import {
3
+ BlendMode,
4
+ FilterMode,
5
+ MipmapMode,
6
+ PaintStyle,
7
+ TileMode,
8
+ } from "../../../skia/types";
9
+ import { surface, importSkia, images } from "../setup";
10
+
11
+ const checkResult = (base64: string, path: string) => {
12
+ const { Skia } = importSkia();
13
+ const rData = Skia.Data.fromBase64(base64);
14
+ const image = Skia.Image.MakeImageFromEncoded(rData)!;
15
+ expect(rData).toBeDefined();
16
+ checkImage(image, docPath(path));
17
+ };
18
+
19
+ describe("Advanced Image Filters", () => {
20
+ itRunsE2eOnly("Arithmetic - Neon Glow", async () => {
21
+ const { skiaLogoPng } = images;
22
+ const base64 = await surface.eval(
23
+ (Skia, ctx) => {
24
+ const sur = Skia.Surface.Make(768, 768)!;
25
+ const canvas = sur.getCanvas();
26
+ const paint = Skia.Paint();
27
+ // Create a blurred version of the image for the glow effect
28
+ const CLAMP = 0;
29
+ const blurFilter = Skia.ImageFilter.MakeBlur(5.0, 5.0, CLAMP);
30
+
31
+ // Original image
32
+ const originalImage = null; // This uses the source bitmap
33
+
34
+ // Neon Glow effect
35
+ const neonGlowFilter = Skia.ImageFilter.MakeArithmetic(
36
+ 0.0, // k1: No multiplication between foreground and background
37
+ 1.5, // k2: Amplify the blurred foreground (the glow)
38
+ 1.0, // k3: Keep the original background fully
39
+ 0.0, // k4: No constant addition
40
+ true, // enforcePMColor: Clamp RGB channels to alpha
41
+ originalImage, // background: Original sharp image
42
+ blurFilter, // foreground: Blurred version creates the glow
43
+ null // cropRect: No cropping
44
+ );
45
+ paint.setImageFilter(neonGlowFilter);
46
+ canvas.drawImage(ctx.skiaLogoPng, 0, 0, paint);
47
+ sur.flush();
48
+ return sur.makeImageSnapshot().encodeToBase64();
49
+ },
50
+ { skiaLogoPng }
51
+ );
52
+ checkResult(base64, "advanced-image-filters/arithmetic-neon-glow.png");
53
+ });
54
+
55
+ itRunsE2eOnly("Crop - Viewport Portal", async () => {
56
+ const { skiaLogoPng } = images;
57
+ const base64 = await surface.eval(
58
+ (Skia, ctx) => {
59
+ const sur = Skia.Surface.Make(768, 768)!;
60
+ const canvas = sur.getCanvas();
61
+
62
+ // Draw background image first
63
+ canvas.drawImage(ctx.skiaLogoPng, 0, 0);
64
+
65
+ // Create a paint for our portal effect
66
+ const paint = Skia.Paint();
67
+
68
+ // Create an input filter that applies a colorization and rotation to the secondary image
69
+ const colorMatrix = [
70
+ 0.8,
71
+ 0.2,
72
+ 0,
73
+ 0,
74
+ 0, // Add some red tint
75
+ 0.2,
76
+ 0.8,
77
+ 0,
78
+ 0,
79
+ 0, // Add some green tint
80
+ 0,
81
+ 0.2,
82
+ 1.0,
83
+ 0,
84
+ 0, // Add some blue boost
85
+ 0,
86
+ 0,
87
+ 0,
88
+ 1,
89
+ 0, // Alpha unchanged
90
+ ];
91
+
92
+ // Create color matrix filter
93
+ const colorFilter = Skia.ColorFilter.MakeMatrix(colorMatrix);
94
+
95
+ // Create the image filter from the secondary image
96
+ const secondaryImageFilter = Skia.ImageFilter.MakeColorFilter(
97
+ colorFilter,
98
+ Skia.ImageFilter.MakeImage(ctx.skiaLogoPng)
99
+ );
100
+
101
+ // Define a circular viewport in the center
102
+ const centerX = 384;
103
+ const centerY = 384;
104
+ const radius = 150;
105
+
106
+ // Create a circular crop rect (positioned to center of canvas)
107
+ const cropRect = Skia.XYWHRect(
108
+ centerX - radius,
109
+ centerY - radius,
110
+ radius * 2,
111
+ radius * 2
112
+ );
113
+
114
+ // Use MIRROR tiling mode for an interesting effect at the edges
115
+ const MIRROR = ctx.TileMode.Mirror;
116
+
117
+ // Create the crop filter with mirror tiling
118
+ const portalFilter = Skia.ImageFilter.MakeCrop(
119
+ cropRect,
120
+ MIRROR,
121
+ secondaryImageFilter
122
+ );
123
+
124
+ // Set the filter to our paint
125
+ paint.setImageFilter(portalFilter);
126
+
127
+ // Draw a circle that will contain our portal effect
128
+ canvas.drawCircle(centerX, centerY, radius, paint);
129
+
130
+ // Optional: Add a stroke around the portal for definition
131
+ const strokePaint = Skia.Paint();
132
+ strokePaint.setStyle(ctx.PaintStyle.Stroke);
133
+ strokePaint.setStrokeWidth(8);
134
+ strokePaint.setColor(Skia.Color("white"));
135
+ canvas.drawCircle(centerX, centerY, radius, strokePaint);
136
+
137
+ sur.flush();
138
+ return sur.makeImageSnapshot().encodeToBase64();
139
+ },
140
+ { skiaLogoPng, PaintStyle, TileMode }
141
+ );
142
+ checkResult(base64, "advanced-image-filters/crop-viewport-portal.png");
143
+ });
144
+
145
+ itRunsE2eOnly("Empty - Silhouette Effect", async () => {
146
+ const { skiaLogoPng } = images;
147
+ const base64 = await surface.eval(
148
+ (Skia, ctx) => {
149
+ const sur = Skia.Surface.Make(768, 768)!;
150
+ const canvas = sur.getCanvas();
151
+
152
+ // Fill background with a gradient
153
+ const bgPaint = Skia.Paint();
154
+ const shader = Skia.Shader.MakeLinearGradient(
155
+ { x: 0, y: 0 },
156
+ { x: 768, y: 768 },
157
+ [
158
+ Skia.Color("rgba(20, 20, 100, 1)"),
159
+ Skia.Color("rgba(100, 40, 150, 1)"),
160
+ ],
161
+ null,
162
+ ctx.TileMode.Clamp
163
+ );
164
+ bgPaint.setShader(shader);
165
+ canvas.drawRect(Skia.XYWHRect(0, 0, 768, 768), bgPaint);
166
+
167
+ // Create our silhouette effect
168
+ const paint = Skia.Paint();
169
+
170
+ // First, we'll create a mask using the original image and a blur
171
+ const imageMask = Skia.ImageFilter.MakeImage(ctx.skiaLogoPng);
172
+ const blurredMask = Skia.ImageFilter.MakeBlur(
173
+ 3,
174
+ 3,
175
+ ctx.TileMode.Decal,
176
+ imageMask
177
+ );
178
+
179
+ // Create an empty filter (transparent black)
180
+ const emptyFilter = Skia.ImageFilter.MakeEmpty();
181
+
182
+ // Combine the mask with empty filter using MakeBlend
183
+ // This creates a silhouette where the image is
184
+ const BLEND_MODE = ctx.BlendMode.Src;
185
+ const silhouetteFilter = Skia.ImageFilter.MakeBlend(
186
+ BLEND_MODE,
187
+ emptyFilter, // Using the empty filter for the black silhouette
188
+ blurredMask // Using the blurred image as the mask
189
+ );
190
+
191
+ // Set our filter to the paint
192
+ paint.setImageFilter(silhouetteFilter);
193
+ paint.setColor(Skia.Color("rgba(0,0,0,0.8)")); // Semi-transparent black
194
+
195
+ // Draw a rectangle covering the entire canvas with our filter
196
+ canvas.drawRect(Skia.XYWHRect(0, 0, 768, 768), paint);
197
+
198
+ // Add some decorative highlights at the edges
199
+ const highlightPaint = Skia.Paint();
200
+ highlightPaint.setColor(Skia.Color("rgba(255, 255, 255, 0.4)"));
201
+ highlightPaint.setImageFilter(blurredMask);
202
+ canvas.drawRect(Skia.XYWHRect(5, 5, 758, 758), highlightPaint);
203
+
204
+ sur.flush();
205
+ return sur.makeImageSnapshot().encodeToBase64();
206
+ },
207
+ { skiaLogoPng, BlendMode, TileMode }
208
+ );
209
+ checkResult(base64, "advanced-image-filters/empty-silhouette.png");
210
+ });
211
+
212
+ itRunsE2eOnly("MakeImage - Dynamic Mosaic", async () => {
213
+ const { skiaLogoPng, mask } = images;
214
+ const base64 = await surface.eval(
215
+ (Skia, ctx) => {
216
+ const sur = Skia.Surface.Make(768, 768)!;
217
+ const canvas = sur.getCanvas();
218
+
219
+ // Draw a background
220
+ const bgPaint = Skia.Paint();
221
+ bgPaint.setColor(Skia.Color("gray"));
222
+ canvas.drawRect(Skia.XYWHRect(0, 0, 768, 768), bgPaint);
223
+
224
+ // Create a mosaic effect using MakeImage filter
225
+ const mosaicPaint = Skia.Paint();
226
+
227
+ // We'll create a 4x4 grid of tiles
228
+ const numTiles = 4;
229
+ const tileSize = 768 / numTiles;
230
+
231
+ // We'll alternate between the two images
232
+ const allImages = [ctx.skiaLogoPng, ctx.mask];
233
+
234
+ // Draw each tile with a different srcRect using MakeImage
235
+ for (let y = 0; y < numTiles; y++) {
236
+ for (let x = 0; x < numTiles; x++) {
237
+ // Alternate images based on checkerboard pattern
238
+ const imageIndex = (x + y) % 2;
239
+ const currentImage = allImages[imageIndex];
240
+
241
+ // Calculate source rectangle (use different areas of the source image)
242
+ // We'll create a dynamic effect by using different parts of the image
243
+ const srcX = (x * currentImage.width()) / numTiles;
244
+ const srcY = (y * currentImage.height()) / numTiles;
245
+ const srcWidth = currentImage.width() / numTiles;
246
+ const srcHeight = currentImage.height() / numTiles;
247
+
248
+ const srcRect = Skia.XYWHRect(srcX, srcY, srcWidth, srcHeight);
249
+
250
+ // Calculate destination rectangle with some margin for visual separation
251
+ const margin = 8;
252
+ const dstX = x * tileSize + margin / 2;
253
+ const dstY = y * tileSize + margin / 2;
254
+ const dstWidth = tileSize - margin;
255
+ const dstHeight = tileSize - margin;
256
+
257
+ const dstRect = Skia.XYWHRect(dstX, dstY, dstWidth, dstHeight);
258
+
259
+ // Create the image filter with Linear filtering for smoother scaling
260
+ const imageFilter = Skia.ImageFilter.MakeImage(
261
+ currentImage,
262
+ srcRect,
263
+ dstRect,
264
+ ctx.FilterMode.Linear,
265
+ ctx.MipmapMode.Linear
266
+ );
267
+
268
+ // Set the filter and draw the tile
269
+ mosaicPaint.setImageFilter(imageFilter);
270
+ canvas.drawRect(dstRect, mosaicPaint);
271
+
272
+ // Add a subtle border around each tile
273
+ const borderPaint = Skia.Paint();
274
+ borderPaint.setStyle(ctx.PaintStyle.Stroke);
275
+ borderPaint.setStrokeWidth(2);
276
+ borderPaint.setColor(Skia.Color("gray"));
277
+ canvas.drawRect(dstRect, borderPaint);
278
+ }
279
+ }
280
+
281
+ sur.flush();
282
+ return sur.makeImageSnapshot().encodeToBase64();
283
+ },
284
+ { skiaLogoPng, FilterMode, MipmapMode, PaintStyle, TileMode, mask }
285
+ );
286
+ checkResult(base64, "advanced-image-filters/makeimage-mosaic.png");
287
+ });
288
+ itRunsE2eOnly("MatrixConvolution - Embossed Metallic Effect", async () => {
289
+ const { skiaLogoPng } = images;
290
+ const base64 = await surface.eval(
291
+ (Skia, ctx) => {
292
+ const sur = Skia.Surface.Make(768, 768)!;
293
+ const canvas = sur.getCanvas();
294
+
295
+ // First, let's create a metallic gradient background
296
+ const bgPaint = Skia.Paint();
297
+ const shader = Skia.Shader.MakeLinearGradient(
298
+ { x: 0, y: 0 },
299
+ { x: 768, y: 768 },
300
+ [
301
+ Skia.Color("rgb(180, 180, 190)"), // Light silver
302
+ Skia.Color("rgb(100, 100, 110)"), // Medium gray
303
+ Skia.Color("rgb(140, 140, 160)"), // Silver again
304
+ Skia.Color("rgb(70, 70, 90)"), // Dark silver
305
+ ],
306
+ [0.0, 0.3, 0.7, 1.0],
307
+ ctx.TileMode.Clamp
308
+ );
309
+ bgPaint.setShader(shader);
310
+ canvas.drawRect(Skia.XYWHRect(0, 0, 768, 768), bgPaint);
311
+
312
+ // Create our emboss effect paint
313
+ const embossPaint = Skia.Paint();
314
+
315
+ // For an emboss effect, we use a 3x3 kernel that highlights
316
+ // edges in a directional way (typically top-left to bottom-right)
317
+ // This creates the illusion of depth
318
+ const kernelSizeX = 3;
319
+ const kernelSizeY = 3;
320
+
321
+ // Emboss kernel - this will create a 3D effect with light coming from top-left
322
+ const kernel = [
323
+ -2,
324
+ -1,
325
+ 0, // Top row
326
+ -1,
327
+ 1,
328
+ 1, // Middle row
329
+ 0,
330
+ 1,
331
+ 2, // Bottom row
332
+ ];
333
+
334
+ // Set kernel parameters
335
+ const gain = 1.0; // Standard scaling
336
+ const bias = 128.0; // Add a mid-gray to make the effect visible
337
+
338
+ // Center the kernel over each pixel
339
+ const kernelOffsetX = 1;
340
+ const kernelOffsetY = 1;
341
+
342
+ // Create the matrix convolution filter
343
+ const embossFilter = Skia.ImageFilter.MakeMatrixConvolution(
344
+ kernelSizeX,
345
+ kernelSizeY,
346
+ kernel,
347
+ gain,
348
+ bias,
349
+ kernelOffsetX,
350
+ kernelOffsetY,
351
+ ctx.TileMode.Clamp, // Use clamp for edge pixels
352
+ false, // Don't convolve alpha to maintain shape
353
+ null, // Use source bitmap as input
354
+ null // No crop rect
355
+ );
356
+
357
+ // Set the filter to our paint
358
+ embossPaint.setImageFilter(embossFilter);
359
+
360
+ // To enhance the metallic look, let's add some color desaturation
361
+ // Grayscale color matrix with a slight blue-silver tint
362
+ const colorMatrix = [
363
+ 0.33,
364
+ 0.33,
365
+ 0.33,
366
+ 0,
367
+ 0, // Red channel
368
+ 0.33,
369
+ 0.33,
370
+ 0.33,
371
+ 0,
372
+ 0, // Green channel
373
+ 0.34,
374
+ 0.34,
375
+ 0.34,
376
+ 0,
377
+ 10, // Blue channel (slightly boosted)
378
+ 0,
379
+ 0,
380
+ 0,
381
+ 1,
382
+ 0, // Alpha channel unchanged
383
+ ];
384
+
385
+ const colorFilter = Skia.ColorFilter.MakeMatrix(colorMatrix);
386
+ embossPaint.setColorFilter(colorFilter);
387
+
388
+ // Now let's draw our image with the emboss effect
389
+ // Scale down slightly to leave a border
390
+ const padding = 40;
391
+ const imageRect = Skia.XYWHRect(
392
+ padding,
393
+ padding,
394
+ 768 - padding * 2,
395
+ 768 - padding * 2
396
+ );
397
+
398
+ canvas.drawImageRect(
399
+ ctx.skiaLogoPng,
400
+ Skia.XYWHRect(
401
+ 0,
402
+ 0,
403
+ ctx.skiaLogoPng.width(),
404
+ ctx.skiaLogoPng.height()
405
+ ),
406
+ imageRect,
407
+ embossPaint
408
+ );
409
+
410
+ // Add a subtle bevel frame to enhance the metallic appearance
411
+ const framePaint = Skia.Paint();
412
+
413
+ // Outer edge - dark shadow
414
+ framePaint.setStyle(ctx.PaintStyle.Stroke);
415
+ framePaint.setStrokeWidth(8);
416
+ framePaint.setColor(Skia.Color("rgba(60, 60, 70, 0.8)"));
417
+ canvas.drawRect(
418
+ Skia.XYWHRect(
419
+ padding - 10,
420
+ padding - 10,
421
+ 768 - padding * 2 + 20,
422
+ 768 - padding * 2 + 20
423
+ ),
424
+ framePaint
425
+ );
426
+
427
+ // Inner edge - highlight
428
+ framePaint.setStrokeWidth(4);
429
+ framePaint.setColor(Skia.Color("rgba(220, 220, 230, 0.8)"));
430
+ canvas.drawRect(
431
+ Skia.XYWHRect(
432
+ padding - 4,
433
+ padding - 4,
434
+ 768 - padding * 2 + 8,
435
+ 768 - padding * 2 + 8
436
+ ),
437
+ framePaint
438
+ );
439
+
440
+ // Add some decorative rivets on the corners to enhance metallic look
441
+ const rivetPaint = Skia.Paint();
442
+ rivetPaint.setColor(Skia.Color("rgb(160, 160, 180)"));
443
+
444
+ // Draw rivets at the corners
445
+ const rivetRadius = 12;
446
+ const rivetOffset = 24;
447
+ const rivetPositions = [
448
+ { x: padding - rivetOffset, y: padding - rivetOffset },
449
+ { x: 768 - padding + rivetOffset, y: padding - rivetOffset },
450
+ { x: padding - rivetOffset, y: 768 - padding + rivetOffset },
451
+ { x: 768 - padding + rivetOffset, y: 768 - padding + rivetOffset },
452
+ ];
453
+
454
+ // Draw each rivet with a metallic gradient
455
+ rivetPositions.forEach((pos) => {
456
+ // Rivet base
457
+ rivetPaint.setShader(
458
+ Skia.Shader.MakeRadialGradient(
459
+ { x: pos.x, y: pos.y },
460
+ rivetRadius,
461
+ [
462
+ Skia.Color("rgb(200, 200, 210)"),
463
+ Skia.Color("rgb(130, 130, 140)"),
464
+ ],
465
+ [0.2, 1.0],
466
+ ctx.TileMode.Clamp
467
+ )
468
+ );
469
+ canvas.drawCircle(pos.x, pos.y, rivetRadius, rivetPaint);
470
+
471
+ // Rivet highlight
472
+ const highlightPaint = Skia.Paint();
473
+ highlightPaint.setColor(Skia.Color("rgba(240, 240, 250, 0.8)"));
474
+ canvas.drawCircle(
475
+ pos.x - 3,
476
+ pos.y - 3,
477
+ rivetRadius / 3,
478
+ highlightPaint
479
+ );
480
+ });
481
+
482
+ sur.flush();
483
+ return sur.makeImageSnapshot().encodeToBase64();
484
+ },
485
+ { skiaLogoPng, TileMode, PaintStyle }
486
+ );
487
+ checkResult(
488
+ base64,
489
+ "advanced-image-filters/matrix-convolution-embossed-metal.png"
490
+ );
491
+ });
492
+ });