-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Description
When you working with transforms, there is a concept that is really handy - Vectors.
Vectors are basically
interface Vector {
x: Animated.SharedValue<number>,
y: Animated.SharedValue<number>,
}But also vectors can be created on UI Thread which makes them
interface Vector {
x: number,
y: number,
}Caveats
This might be handy not for everyone, but still, I find it really useful. The possibility to access .value and get undefined not that great.
Motivation
I created an interface to do some math with vectors where you can pass both types and it will figure it out. But the only problem - then it’s easy to forget to access .value when it’s a shared value vector or you can do it on a regular vector which is not holding shared values and get a crash or undefined.
That’s why I went with the approach where you need to access .value even though it’s not a shared value.
You can find the implementation here:
wcandillon/react-native-redash#373
But still, with complex code, it looks kinda ugly - too many of those .value, because we now have two values for each thing - x and y.
So I thought we can use kinda getter/setter for each property, so every time you access vector.x or vector.y - it actually reads the value of some shared value we have under the hood.
But it doesn’t work because seems like getters are stripped out when we capture objects with them.
Code example
This code logs:
Getter false
Getter false
Mapper {"getter": 0, "sv": 0}
Mapper {"getter": 0, "sv": 0}
Setter false
Mapper {"getter": 0, "sv": 100}
const useSharedValueTest = (value) => {
const _sv = useSharedValue(value);
const obj = {
_sv,
};
function get() {
'worklet';
console.log('Getter', _WORKLET);
return _sv.value;
}
function set(nextValue) {
'worklet';
console.log('Setter', _WORKLET);
_sv.value = nextValue;
}
Object.defineProperty(obj, 'x', {
get,
set,
});
return obj;
};
const vector = useSharedValueTest(0);
setTimeout(() => {
runOnUI(() => {
vector.x = 100;
})();
}, 1000);
useAnimatedStyle(() => {
console.log('Mapper', {
sv: vector._sv.value,
getter: vector.x,
});
return {};
}, []);