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 | 9x 181x 181x 181x 9x 9x 115x 9x 60x 9x 30x 30x 30x 30x 30x 30x 30x 30x 30x 30x 67x 268x 201x 67x 67x | import { mix } from './mix';
import { hsla, rgba, hex, Color } from 'style-value-types';
import { invariant } from 'hey-listen';
// Linear color space blending
// Explained https://www.youtube.com/watch?v=LKnqECcg6Gw
// Demonstrated http://codepen.io/osublake/pen/xGVVaN
export const mixLinearColor = (from: number, to: number, v: number) => {
const fromExpo = from * from;
const toExpo = to * to;
return Math.sqrt(Math.max(0, v * (toExpo - fromExpo) + fromExpo));
};
const colorTypes = [hex, rgba, hsla];
const getColorType = (v: Color | string) =>
colorTypes.find(type => type.test(v));
const notAnimatable = (color: Color | string) =>
`'${color}' is not an animatable color. Use the equivalent color code instead.`;
export const mixColor = (from: Color | string, to: Color | string) => {
const fromColorType = getColorType(from);
const toColorType = getColorType(to);
invariant(!!fromColorType, notAnimatable(from));
invariant(!!toColorType, notAnimatable(to));
invariant(
fromColorType.transform === toColorType.transform,
'Both colors must be hex/RGBA, OR both must be HSLA.'
);
const fromColor = fromColorType.parse(from);
const toColor = toColorType.parse(to);
const blended = { ...fromColor };
// Only use the linear blending function for rgba and hex
const mixFunc = fromColorType === hsla ? mix : mixLinearColor;
return (v: number) => {
for (const key in blended) {
if (key !== 'alpha') {
blended[key] = mixFunc(fromColor[key], toColor[key], v);
}
}
blended.alpha = mix(fromColor.alpha, toColor.alpha, v);
return fromColorType.transform(blended);
};
};
|