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
This commit is contained in:
Sean Kelley 2016-05-17 10:10:23 -07:00 committed by Facebook Github Bot 2
parent 9092198b1b
commit 908041b80b
2 changed files with 11 additions and 1 deletions

View File

@ -233,7 +233,7 @@ function createInterpolationFromStringOutputRange(
// 'rgba(${interpolations[0](input)}, ${interpolations[1](input)}, ...' // 'rgba(${interpolations[0](input)}, ${interpolations[1](input)}, ...'
return outputRange[0].replace(stringShapeRegex, () => { return outputRange[0].replace(stringShapeRegex, () => {
const val = +interpolations[i++](input); 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); return String(rounded);
}); });
}; };

View File

@ -294,4 +294,14 @@ describe('Interpolation', () => {
outputRange: ['20deg', '30rad'], outputRange: ['20deg', '30rad'],
})).toThrow(); })).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)');
});
}); });