Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 37x 38x 12x 9x 3x 8x 15x 15x 32x 15x 26x 49x 26x 8x 2x 2x 2x 5x 5x 2x 2x 5x 2x 28x 28x 28x 28x 28x 28x 54x 38x 16x 1x 15x 28x 8x 14x 14x 14x 14x 13x | import { color, complex, RGBA, HSLA } from 'style-value-types';
import { mix } from './mix';
import { mixColor } from './mix-color';
import { isNum } from './inc';
import { pipe } from './pipe';
import { invariant } from 'hey-listen';
type MixComplex = (p: number) => string;
type BlendableArray = Array<number | RGBA | HSLA | string>;
type BlendableObject = {
[key: string]: string | number | RGBA | HSLA;
};
function getMixer(origin: any, target: any) {
if (isNum(origin)) {
return (v: number) => mix(origin, target as number, v);
} else if (color.test(origin)) {
return mixColor(origin, target as HSLA | RGBA | string);
} else {
return mixComplex(origin as string, target as string);
}
}
export const mixArray = (from: BlendableArray, to: BlendableArray) => {
const output = [...from];
const numValues = output.length;
const blendValue = from.map((fromThis, i) => getMixer(fromThis, to[i]));
return (v: number) => {
for (let i = 0; i < numValues; i++) {
output[i] = blendValue[i](v);
}
return output;
};
};
export const mixObject = (origin: BlendableObject, target: BlendableObject) => {
const output = { ...origin, ...target };
const blendValue: { [key: string]: (v: number) => any } = {};
for (const key in output) {
Eif (origin[key] !== undefined && target[key] !== undefined) {
blendValue[key] = getMixer(origin[key], target[key]);
}
}
return (v: number) => {
for (const key in blendValue) {
output[key] = blendValue[key](v);
}
return output;
};
};
function analyse(value: string) {
const parsed = complex.parse(value);
const numValues = parsed.length;
let numNumbers = 0;
let numRGB = 0;
let numHSL = 0;
for (let i = 0; i < numValues; i++) {
// Parsed complex values return with colors first, so if we've seen any number
// we're already past that part of the array and don't need to continue running typeof
if (numNumbers || typeof parsed[i] === 'number') {
numNumbers++;
} else {
if ((parsed[i] as HSLA).hue !== undefined) {
numHSL++;
} else {
numRGB++;
}
}
}
return { parsed, numNumbers, numRGB, numHSL };
}
export const mixComplex = (origin: string, target: string): MixComplex => {
const template = complex.createTransformer(target);
const originStats = analyse(origin);
const targetStats = analyse(target);
// Test if both values have the same number of each value type (number/rgb/hsla), or that the origin
// has the same or more numbers as the target, and throw if not.
invariant(
originStats.numHSL === targetStats.numHSL &&
originStats.numRGB === targetStats.numRGB &&
originStats.numNumbers >= targetStats.numNumbers,
`Complex values '${origin}' and '${target}' too different to mix. Ensure all colors are of the same type.`
);
return pipe(
mixArray(originStats.parsed, targetStats.parsed),
template
) as MixComplex;
};
|