mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-24 04:16:00 +08:00
Reimplement color processing
Summary:
**Problem:**
As I was trying to document what color formats we supported, I realized that our current implementation based on the open source project tinycolor supported some crazy things. A few examples that were all valid:
```
tinycolor('abc')
tinycolor(' #abc ')
tinycolor('##abc')
tinycolor('rgb 255 0 0')
tinycolor('RGBA(0, 1, 2)')
tinycolor('rgb (0, 1, 2)')
tinycolor('hsv(0, 1, 2)')
tinycolor({r: 10, g: 10, b: 10})
tinycolor('hsl(1%, 2, 3)')
tinycolor('rgb(1.0, 2.0, 3.0)')
tinycolor('rgb(1%, 2%, 3%)')
```
The integrations of tinycolor were also really bad. processColor added "support" for pure numbers and an array of colors!?? ColorPropTypes did some crazy trim().toString() and repeated a bad error message twice.
**Solution:**
While iteratively cleaning the file, I eventually ended up reimplementing it entierly. Major changes are:
- The API is now dead simple: returns null if it doesn't parse or returns the int32 representation of the color
- Stricter parsing of at
Closes https://github.com/facebook/react-native/pull/5529
Reviewed By: svcscm
Differential Revision: D2872015
Pulled By: nicklockwood
fb-gh-sync-id: df78244eefce6cf8e8ed2ea51f58d6b232de16f9
This commit is contained in:
committed by
facebook-github-bot-8
parent
715081c4da
commit
c8a0a3eff6
@@ -9,9 +9,10 @@
|
||||
* @providesModule Interpolation
|
||||
* @flow
|
||||
*/
|
||||
/* eslint no-bitwise: 0 */
|
||||
'use strict';
|
||||
|
||||
var tinycolor = require('tinycolor');
|
||||
var normalizeColor = require('normalizeColor');
|
||||
|
||||
// TODO(#7644673): fix this hack once github jest actually checks invariants
|
||||
var invariant = function(condition, message) {
|
||||
@@ -164,16 +165,20 @@ function interpolate(
|
||||
return result;
|
||||
}
|
||||
|
||||
function colorToRgba(
|
||||
input: string
|
||||
): string {
|
||||
var color = tinycolor(input);
|
||||
if (color.isValid()) {
|
||||
var {r, g, b, a} = color.toRgb();
|
||||
return `rgba(${r}, ${g}, ${b}, ${a === undefined ? 1 : a})`;
|
||||
} else {
|
||||
function colorToRgba(input: string): string {
|
||||
var int32Color = normalizeColor(input);
|
||||
if (int32Color === null) {
|
||||
return input;
|
||||
}
|
||||
|
||||
int32Color = int32Color || 0; // $FlowIssue
|
||||
|
||||
var a = ((int32Color & 0xff000000) >>> 24) / 255;
|
||||
var r = (int32Color & 0x00ff0000) >>> 16;
|
||||
var g = (int32Color & 0x0000ff00) >>> 8;
|
||||
var b = int32Color & 0x000000ff;
|
||||
|
||||
return `rgba(${r}, ${g}, ${b}, ${a})`;
|
||||
}
|
||||
|
||||
var stringShapeRegex = /[0-9\.-]+/g;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
jest
|
||||
.dontMock('Interpolation')
|
||||
.dontMock('Easing')
|
||||
.dontMock('tinycolor');
|
||||
.dontMock('normalizeColor');
|
||||
|
||||
var Interpolation = require('Interpolation');
|
||||
var Easing = require('Easing');
|
||||
@@ -216,12 +216,12 @@ describe('Interpolation', () => {
|
||||
it('should work with output ranges as string', () => {
|
||||
var interpolation = Interpolation.create({
|
||||
inputRange: [0, 1],
|
||||
outputRange: ['rgba(0, 100, 200, 0)', 'rgba(50, 150, 250, 0.5)'],
|
||||
outputRange: ['rgba(0, 100, 200, 0)', 'rgba(50, 150, 250, 0.4)'],
|
||||
});
|
||||
|
||||
expect(interpolation(0)).toBe('rgba(0, 100, 200, 0)');
|
||||
expect(interpolation(0.5)).toBe('rgba(25, 125, 225, 0.25)');
|
||||
expect(interpolation(1)).toBe('rgba(50, 150, 250, 0.5)');
|
||||
expect(interpolation(0.5)).toBe('rgba(25, 125, 225, 0.2)');
|
||||
expect(interpolation(1)).toBe('rgba(50, 150, 250, 0.4)');
|
||||
});
|
||||
|
||||
it('should work with output ranges as short hex string', () => {
|
||||
@@ -249,11 +249,11 @@ describe('Interpolation', () => {
|
||||
it('should work with output ranges with mixed hex and rgba strings', () => {
|
||||
var interpolation = Interpolation.create({
|
||||
inputRange: [0, 1],
|
||||
outputRange: ['rgba(100, 120, 140, .5)', '#87FC70'],
|
||||
outputRange: ['rgba(100, 120, 140, .4)', '#87FC70'],
|
||||
});
|
||||
|
||||
expect(interpolation(0)).toBe('rgba(100, 120, 140, 0.5)');
|
||||
expect(interpolation(0.5)).toBe('rgba(117.5, 186, 126, 0.75)');
|
||||
expect(interpolation(0)).toBe('rgba(100, 120, 140, 0.4)');
|
||||
expect(interpolation(0.5)).toBe('rgba(117.5, 186, 126, 0.7)');
|
||||
expect(interpolation(1)).toBe('rgba(135, 252, 112, 1)');
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user