-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
make reanimated work in web #1886
Conversation
FYI setNativeProps will not be supported in the new RN architecture and is being removed from RNWeb too |
@necolas good point. Just could probably not be a direct exposure of the DOM ref since they set all attributes in sequence and we'd need all of the new props to calculate a new |
Could you add some examples to e.g. |
@WoLewicki I can give it a spin. By the way, I'm just going at that |
and I added an example :) |
Also, maybe I should add some explanation on what this is doing and how it is interacting. From the users perspective:
This is the example from the docs import React from 'react';
import { StyleSheet } from 'react-native';
import Animated, {
useSharedValue,
useAnimatedProps,
} from 'react-native-reanimated';
import Svg, { Path } from 'react-native-svg';
const AnimatedPath = Animated.createAnimatedComponent(Path);
function App() {
const radius = useSharedValue(50);
const animatedProps = useAnimatedProps(() => {
// draw a circle
const path = `
M 100, 100
m -${radius.value}, 0
a ${radius.value},${radius.value} 0 1,0 ${radius.value * 2},0
a ${radius.value},${radius.value} 0 1,0 ${-radius.value * 2},0
`;
return {
d: path,
};
});
// attach animated props to an SVG path using animatedProps
return (
<Svg>
<AnimatedPath animatedProps={animatedProps} fill="black" />
</Svg>
);
} Now, let's look at the react-native-reanimated internals of those "off-render-updates": if (typeof component.setNativeProps === 'function') {
setNativeProps(component, rawStyles);
} else if (Object.keys(component.props).length > 0) {
Object.keys(component.props).forEach((key) => {
if (!rawStyles[key]) {
return;
}
const dashedKey = key.replace(/[A-Z]/g, (m) => '-' + m.toLowerCase());
component._touchableNode.setAttribute(dashedKey, rawStyles[key]);
});
} else {
console.warn('It is not possible to manipulate component');
} The relevant part:
Now, "setting each attribute individually" faces two problems from the side of
Hence, my approach here:
I hope this explains most of my thought process behind this PR :) PS: All that said, there might be merit to start a discussion over in https://github.com/software-mansion/react-native-reanimated if it might not be possible to add a PS2: I opened a discussion that you can find at software-mansion/react-native-reanimated#3633, but not only adding this for |
So would it be possible to rather change how reanimated's web code works instead of those hacky solutions on the |
@WoLewicki assuming react-native-reanimated would change their internals (and quite a lot of them), yes. Otherwise, no. To be honest, this PR doesn't really change a lot behaviour that was there before. Moving the The only thing that is changed on the outside interface is that calling Benefit of getting this PR in is that this would also mean it probably works with different animation implementations that call |
After consultation with @kmagiera we came to a conclusion that the first version of this PR using |
@WoLewicki sure, I reverted those files. |
Seems these CI errors come from the example app, or rather from the dependency to |
Yeah, it seems right to not check other libraries' types in PRs for this library 😅 |
I checked the current implementation and the rectangle seems to be stuck in one place, not animating. Also, could you add a |
I've changed it to red, so it's visible on Android as well (I don't have an iOS device to check at hand). For me, the rectangle is animating in both Chrome and Firefox. I'm not really sure what's going on there.. :/ |
Hmm, I can reproduce that on a different machine. Maybe I am the one with the stale cache. I'll look into it. |
Got it. The original code only applied changes to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks for your contribution 🎉
Lol last minute fix, I'm sorry! |
I noticed that |
Ok, could you also run |
I'm on a Linux machine, so I don't have
To assign properties not on |
Ok so could you please add a comment in code with the link to the relevant code you just linked? |
Sure :) Are you happy with it like that? |
Yeah, looks good now 🚀 |
Summary
Up until now, trying to use
reanimated
withreact-native-svg
inreact-native-web
resulted in an error.This adds a
setNativeProps
function to the web implementation to directly modify thetransform
andstyle
props on a SVGElementref
.Since there is a need to track the "last merged props" and those need to be reset on every render, the
render
method has been moved into theWebShape
class and atag
string property has been added.As
g
had some extra handling forx
andy
, aprepareProps
function was added as well.Test Plan
Here is a video of me dragging a
<g>
with a nested<image>
in chome: https://www.loom.com/share/675405537d9d41a792432ebf41636047What's required for testing (prerequisites)?
Just run any reanimated svg in the browser instead of a device.
What are the steps to reproduce (after prerequisites)?
Run any animation.
Compatibility
Checklist
README.md
__tests__
folder