From 908041b80b859187407b840d80541c28c2f9d8eb Mon Sep 17 00:00:00 2001 From: Sean Kelley Date: Tue, 17 May 2016 10:10:23 -0700 Subject: [PATCH] Round alpha channel when interpolating colors to the nearest thousandth. Summary: This fixes an issue where animations for values near zero could end up formatted with exponents (e.g. `1.452e-10`), which is not valid for an `rgba` color spec. This commit arbitrarily rounds it to the nearest thousandth to prevent this type of formatting while still maintaining high-enough resolution in the alpha channel. One way this could bubble up to the user is as PropType validation failures: ``` Failed propType: Invalid prop `backgroundColor` supplied to `RCTView`: rgba(0, 0, 0, 9.838983123336224e-7) ``` Closes https://github.com/facebook/react-native/pull/7597 Differential Revision: D3310941 Pulled By: vjeux fbshipit-source-id: 0c95facaef5b69c021662af9fb6f268d890ecc3e --- Libraries/Animated/src/Interpolation.js | 2 +- Libraries/Animated/src/__tests__/Interpolation-test.js | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Libraries/Animated/src/Interpolation.js b/Libraries/Animated/src/Interpolation.js index 90f90efa1..32d363ccb 100644 --- a/Libraries/Animated/src/Interpolation.js +++ b/Libraries/Animated/src/Interpolation.js @@ -233,7 +233,7 @@ function createInterpolationFromStringOutputRange( // 'rgba(${interpolations[0](input)}, ${interpolations[1](input)}, ...' return outputRange[0].replace(stringShapeRegex, () => { const val = +interpolations[i++](input); - const rounded = shouldRound && i < 4 ? Math.round(val) : val; + const rounded = shouldRound && i < 4 ? Math.round(val) : Math.round(val * 1000) / 1000; return String(rounded); }); }; diff --git a/Libraries/Animated/src/__tests__/Interpolation-test.js b/Libraries/Animated/src/__tests__/Interpolation-test.js index af8677ac2..54d3ee460 100644 --- a/Libraries/Animated/src/__tests__/Interpolation-test.js +++ b/Libraries/Animated/src/__tests__/Interpolation-test.js @@ -294,4 +294,14 @@ describe('Interpolation', () => { outputRange: ['20deg', '30rad'], })).toThrow(); }); + + it('should round the alpha channel of a color to the nearest thousandth', () => { + var interpolation = Interpolation.create({ + inputRange: [0, 1], + outputRange: ['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, 1)'], + }); + + expect(interpolation(1e-12)).toBe('rgba(0, 0, 0, 0)'); + expect(interpolation(2 / 3)).toBe('rgba(0, 0, 0, 0.667)'); + }); });