Fix normalization of degrees in AnimatedInterpolation (#36645)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/36645

This broke while changing the AnimatedInterpolation back in D40571873 and D40632443, as I assumed the native side would be able to correctly handle values such as '1rad'. However these were being sent over as strings, and were thus using the string interpolation path, which does not work here.

Instead, handle both `deg` and `rad` explicitly when generating the config in JS.

Resolves issue https://github.com/facebook/react-native/issues/36608

Changelog: [General][Fixed] Resolves Animated.Value.interpolate results in NaN when output is in radians

Reviewed By: yungsters

Differential Revision: D44406034

fbshipit-source-id: fe0f3df16f2b8ec6c31f9359e4706cacc72b9951
This commit is contained in:
Pieter De Baets
2023-03-27 12:38:16 -07:00
committed by Facebook GitHub Bot
parent 33612906d9
commit ae0d714bbd
2 changed files with 22 additions and 3 deletions
@@ -562,10 +562,13 @@ function transformDataType(value: number | string): number | string {
if (typeof value !== 'string') {
return value;
}
if (/deg$/.test(value)) {
// Normalize degrees and radians to a number expressed in radians
if (value.endsWith('deg')) {
const degrees = parseFloat(value) || 0;
const radians = (degrees * Math.PI) / 180.0;
return radians;
return (degrees * Math.PI) / 180.0;
} else if (value.endsWith('rad')) {
return parseFloat(value) || 0;
} else {
return value;
}
@@ -349,4 +349,20 @@ describe('Interpolation', () => {
expect(interpolation(1e-12)).toBe('rgba(0, 0, 0, 0)');
expect(interpolation(2 / 3)).toBe('rgba(0, 0, 0, 0.667)');
});
it.each([
['radians', ['1rad', '2rad'], [1, 2]],
['degrees', ['90deg', '180deg'], [Math.PI / 2, Math.PI]],
['numbers', [1024, Math.PI], [1024, Math.PI]],
['unknown', ['5foo', '10foo'], ['5foo', '10foo']],
])(
'should convert %s to numbers in the native config',
(_, outputRange, expected) => {
const config = new AnimatedInterpolation(
{},
{inputRange: [0, 1], outputRange},
).__getNativeConfig();
expect(config.outputRange).toEqual(expected);
},
);
});