Skip to content

Commit

Permalink
Support hex values in outputRange
Browse files Browse the repository at this point in the history
Summary: 1. Should I add an example of this to the UIExplorer Animation example?

2. Should I support mixing hex and rgba values in outputRange? It is possible with this implementation, but may cause confusion
Closes facebook#3177

Reviewed By: @​svcscm

Differential Revision: D2506947

Pulled By: @vjeux
  • Loading branch information
dralletje authored and Crash-- committed Dec 24, 2015
1 parent 1098219 commit a0971ee
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 6 deletions.
15 changes: 15 additions & 0 deletions Libraries/Animated/src/Interpolation.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
*/
'use strict';

var tinycolor = require('tinycolor2');

// TODO(#7644673): fix this hack once github jest actually checks invariants
var invariant = function(condition, message) {
if (!condition) {
Expand Down Expand Up @@ -163,6 +165,18 @@ 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 {
return input;
}
}

var stringShapeRegex = /[0-9\.-]+/g;

/**
Expand All @@ -178,6 +192,7 @@ function createInterpolationFromStringOutputRange(
): (input: number) => string {
var outputRange: Array<string> = (config.outputRange: any);
invariant(outputRange.length >= 2, 'Bad output range');
outputRange = outputRange.map(colorToRgba);
checkPattern(outputRange);

// ['rgba(0, 100, 200, 0)', 'rgba(50, 150, 250, 0.5)']
Expand Down
53 changes: 47 additions & 6 deletions Libraries/Animated/src/__tests__/Interpolation-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

jest
.dontMock('Interpolation')
.dontMock('Easing');
.dontMock('Easing')
.dontMock('tinycolor2');

var Interpolation = require('Interpolation');
var Easing = require('Easing');
Expand Down Expand Up @@ -223,6 +224,39 @@ describe('Interpolation', () => {
expect(interpolation(1)).toBe('rgba(50, 150, 250, 0.5)');
});

it('should work with output ranges as short hex string', () => {
var interpolation = Interpolation.create({
inputRange: [0, 1],
outputRange: ['#024', '#9BF'],
});

expect(interpolation(0)).toBe('rgba(0, 34, 68, 1)');
expect(interpolation(0.5)).toBe('rgba(76.5, 110.5, 161.5, 1)');
expect(interpolation(1)).toBe('rgba(153, 187, 255, 1)');
});

it('should work with output ranges as long hex string', () => {
var interpolation = Interpolation.create({
inputRange: [0, 1],
outputRange: ['#FF9500', '#87FC70'],
});

expect(interpolation(0)).toBe('rgba(255, 149, 0, 1)');
expect(interpolation(0.5)).toBe('rgba(195, 200.5, 56, 1)');
expect(interpolation(1)).toBe('rgba(135, 252, 112, 1)');
});

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'],
});

expect(interpolation(0)).toBe('rgba(100, 120, 140, 0.5)');
expect(interpolation(0.5)).toBe('rgba(117.5, 186, 126, 0.75)');
expect(interpolation(1)).toBe('rgba(135, 252, 112, 1)');
});

it('should work with negative and decimal values in string ranges', () => {
var interpolation = Interpolation.create({
inputRange: [0, 1],
Expand All @@ -242,12 +276,19 @@ describe('Interpolation', () => {
expect(() => { interpolation('45rad'); }).toThrow();
});

it('should crash when defining output range with different pattern', () => {
expect(() => Interpolation.create({
inputRange: [0, 1],
outputRange: ['rgba(0, 100, 200, 0)', 'rgb(50, 150, 250)'],
})).toThrow();
it('should support a mix of color patterns', () => {
var interpolation = Interpolation.create({
inputRange: [0, 1, 2],
outputRange: ['rgba(0, 100, 200, 0)', 'rgb(50, 150, 250)', 'red'],
});

expect(interpolation(0)).toBe('rgba(0, 100, 200, 0)');
expect(interpolation(0.5)).toBe('rgba(25, 125, 225, 0.5)');
expect(interpolation(1.5)).toBe('rgba(152.5, 75, 125, 1)');
expect(interpolation(2)).toBe('rgba(255, 0, 0, 1)');
});

it('should crash when defining output range with different pattern', () => {
expect(() => Interpolation.create({
inputRange: [0, 1],
outputRange: ['20deg', '30rad'],
Expand Down

0 comments on commit a0971ee

Please sign in to comment.