add react-strict-animated library
This introduces a new package to the RSD repo that provides a subset of React Native's API that works on both web and native, and built with integration of react-strict-dom in mind. The native implementation is largely a thin passthrough to the proper Animated API and some settings pre-configured (such as useAnimatedDriver always being enabled).
The web side is a new Animated implementation that ends up being driven by the Web Animations API.
workflow: benchmarks/size
Comparison of minified (terser) and compressed (brotli) size results, measured in bytes. Smaller is better.
| Results | Base | Patch | Ratio | |
|---|---|---|---|---|
| react-strict-dom/dist/web/index.js | ||||
| · compressed | 3,251 | 3,251 | 1.00 | |
| · minified | 10,375 | 10,375 | 1.00 | |
| react-strict-dom/dist/web/runtime.js | ||||
| · compressed | 1,645 | 1,645 | 1.00 | |
| · minified | 4,131 | 4,131 | 1.00 | |
| react-strict-dom/dist/native/index.js | ||||
| · compressed | 16,232 | 16,232 | 1.00 | |
| · minified | 62,962 | 62,962 | 1.00 | |
| react-strict-animated/dist/web/index.js | ||||
| · compressed | 6,896 | |||
| · minified | 23,698 | |||
| react-strict-animated/dist/native/index.js | ||||
| · compressed | 586 | |||
| · minified | 1,801 |
workflow: benchmarks/perf (native)
Comparison of performance test results, measured in operations per second. Larger is better.
| Results | Base | Patch | Ratio | |
|---|---|---|---|---|
| css.create | ||||
| · small | 1,142,268 | 1,146,256 | 1.00 | + |
| · small with units | 492,431 | 494,718 | 1.00 | + |
| · small with variables | 668,880 | 672,392 | 1.01 | + |
| · several small | 352,288 | 354,471 | 1.01 | + |
| · large | 202,182 | 200,826 | 0.99 | - |
| · large with polyfills | 148,034 | 149,301 | 1.01 | + |
| · complex | 102,183 | 103,124 | 1.01 | + |
| · unsupported | 211,894 | 213,841 | 1.01 | + |
| css.createTheme | ||||
| · simple theme | 228,835 | 226,694 | 0.99 | - |
| · polyfill theme | 216,403 | 214,832 | 0.99 | - |
| css.props | ||||
| · small | 231,931 | 230,923 | 1.00 | - |
| · small with units | 187,373 | 189,235 | 1.01 | + |
| · small with variables | 112,861 | 112,824 | 1.00 | - |
| · small with variables of units | 82,309 | 82,446 | 1.00 | + |
| · large | 96,865 | 96,936 | 1.00 | + |
| · large with polyfills | 37,959 | 38,365 | 1.01 | + |
| · complex | 21,932 | 22,025 | 1.00 | + |
| · unsupported | 139,215 | 140,146 | 1.01 | + |
| · simple merge | 160,013 | 160,071 | 1.00 | + |
| · wide merge | 16,885 | 16,890 | 1.00 | + |
| · deep merge | 16,605 | 16,646 | 1.00 | + |
| · themed merge | 32,372 | 32,301 | 1.00 | - |
Thanks for bringing the animation library you've made to the OSS project! Want a hand with the build and package parts?
Thanks for bringing the animation library you've made to the OSS project! Want a hand with the build and package parts?
So I recreated the build system that's basically exactly like how RSD is built but I'm running into some issues related to the generate-types utility:
- As you can tell from the checks the
generate-typesoutput contains flow errors - I had to update my implementation to stop using the
hooksyntax as that broke thegenerate-typesscript. - Upon inspection of the typescript output of
generate-typesit looks like its outputting a bunch ofanys because it says that features likeReact.PropsOfandReact.RefOfis unsupported.
I've tried digging into how to resolve the type generation issues but haven't had any luck yet :/
We can try upgrading the translator package. And if that doesn't work, report the issues to the flow team
Okay I updated the flow-api-translator which didn't seem to do much but I did find a way to reorganize the exports so that there were no more flow errors after building.
Hey @vincentriemer, what's the plan here? Did you make any progress on incorporating the viewport scaling polyfill into the animated values?
@necolas @vincentriemer great to see progress on cross-platform animations.
Was wondering and trying to understand better how this relates to: https://github.com/facebook/react-strict-dom/issues/3
having a polyfill for css.keyframes seems more in line with the overall "web first" API of react-strict-dom?
Would it eventually be possible to build polyfill similar to the one for CSS transitions by internally using react-strict-animated?
Also curious about what was touched on this comment: https://github.com/facebook/react-strict-dom/issues/3#issuecomment-2585212069 I assume the Animated vs reanimated topic can be controversial, but finding a way to make the animation library opt-in may help in quicker adoption (I'm guessing here that in the long term Animated on react-native will want to address the issues that reanimated tries to fix?)
The whole JS thread vs UI thread topic is also quite interesting in relation to react-strict-dom: in a way having something like a UI thread is in sync with what happens on web where css animations runs on the gpu.
Probably some of those comments have already been discussed in depth in the RN community, and for sure I lack some context, but I'm trying to gauge the position and vision of RSD on this.
This animation library enables different things to CSS keyframes
The plan is for Animated and Reanimated to share the same C++ backend. We use the C++ Animated internally; no need to switch out for Reanimated. That will make its way to OSS eventually
Updated PR with:
- viewport scaling hook exposed from the react-strict-dom package
- viewport scaling of the translateX/Y transform properties
- baseline unit testing coverage
viewport scaling hook exposed from the react-strict-dom package
Having to expose this part of the implementation details is unfortunate. Was this the best of a bunch of bad options? Is the internal version of this library just not handling viewport scaling at all yet?
Would also like to understand a bit more the role of normalizeColor
I mean the other option to support it would be to have the package track viewport scaling all on its own, and yeah the internal version isn't taking viewport scaling into account yet I've been focusing on this version first.
normalizeColor is something we technically aren't using as currently I haven't enabled any color-based properties to be animatable but if we do ever add any color-based properties normalizeColor is important because interpolation is fundamentally done on numeric values, but that's not really how we represent colors in RN/web, so if you want to consistently interpolate between different colors its easier to first normalize them to consistent representation, in this case an rgba array of numbers.
FWIW if I could I would just have this implementation point to the normalizeColor that lives in RN but that's an internal file I can't reference so the one that's in this codebase is more or less a duplicate of it.
if I could I would just have this implementation point to the normalizeColor that lives in RN
We have a separate package for it these days I believe: https://www.npmjs.com/package/@react-native/normalize-colors
For the current approach we could export useViewportScale prefixed with unstable_ or DO_NOT_USE_ to avoid it looking like "blessed" public API. Don't want to hold this up on figuring out something "ideal".
I don't have any great ideas for a clean relationship between packages. This is my understanding of the options and tradeoffs. Sharing in case anyone has suggestions.
Part of RSD package
- Difficulty importing from
react-strict-domrather than relative imports - Exported as subpath:
react-strict-dom/animated - Can share RN imports and other internals with RSD package
- No need to export internals / "temporary" workarounds like useViewportScale
New package
- Built only on public API of RSD
- Exported as separate new package:
react-strict-animatedwith RSD dependency - Can share imports or internals with RSD
- Needs to modify RSD exports to include internals
- Can't potentially be incorporated into RSD babel transform