From dcf886787029235ecc1cd3e8f2893241e7543b11 Mon Sep 17 00:00:00 2001 From: Pieter De Baets Date: Sun, 26 Mar 2023 13:27:04 -0700 Subject: [PATCH] Fix normalization of degrees in AnimatedInterpolation Summary: 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 Differential Revision: D44406034 fbshipit-source-id: ea95f557d594a1f55bedd7c5e3a95ef36bc68ff2 --- .../Libraries/Animated/NativeAnimatedHelper.js | 7 +++++-- .../Animated/__tests__/Interpolation-test.js | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/react-native/Libraries/Animated/NativeAnimatedHelper.js b/packages/react-native/Libraries/Animated/NativeAnimatedHelper.js index 2dd197617641be..3c5ac55493f30e 100644 --- a/packages/react-native/Libraries/Animated/NativeAnimatedHelper.js +++ b/packages/react-native/Libraries/Animated/NativeAnimatedHelper.js @@ -562,10 +562,13 @@ function transformDataType(value: number | string): number | string { if (typeof value !== 'string') { return value; } + + // Normalize degrees and radians to a number expressed in radians if (/deg$/.test(value)) { const degrees = parseFloat(value) || 0; - const radians = (degrees * Math.PI) / 180.0; - return radians; + return (degrees * Math.PI) / 180.0; + } else if (/rad$/.test(value)) { + return parseFloat(value) || 0; } else { return value; } diff --git a/packages/react-native/Libraries/Animated/__tests__/Interpolation-test.js b/packages/react-native/Libraries/Animated/__tests__/Interpolation-test.js index 0e8e342da760ea..9726b919121898 100644 --- a/packages/react-native/Libraries/Animated/__tests__/Interpolation-test.js +++ b/packages/react-native/Libraries/Animated/__tests__/Interpolation-test.js @@ -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); + }, + ); });