UNPKG

6.34 kBJavaScriptView Raw
1'use strict';
2
3import { hsvToColor, RGBtoHSV, rgbaColor, processColor, red, green, blue, opacity } from "./Colors.js";
4import { makeMutable } from "./core.js";
5import { Extrapolation, interpolate } from "./interpolation.js";
6import { useSharedValue } from "./hook/useSharedValue.js";
7import { ReanimatedError } from "./errors.js";
8
9/** @deprecated Please use Extrapolation instead */
10export const Extrapolate = Extrapolation;
11
12/**
13 * Options for color interpolation.
14 *
15 * @param gamma - Gamma value used in gamma correction. Defaults to `2.2`.
16 * @param useCorrectedHSVInterpolation - Whether to reduce the number of colors
17 * the interpolation has to go through. Defaults to `true`.
18 */
19
20const interpolateColorsHSV = (value, inputRange, colors, options) => {
21 'worklet';
22
23 let h = 0;
24 const {
25 useCorrectedHSVInterpolation = true
26 } = options;
27 if (useCorrectedHSVInterpolation) {
28 // if the difference between hues in a range is > 180 deg
29 // then move the hue at the right end of the range +/- 360 deg
30 // and add the next point in the original place + 0.00001 with original hue
31 // to not break the next range
32 const correctedInputRange = [inputRange[0]];
33 const originalH = colors.h;
34 const correctedH = [originalH[0]];
35 for (let i = 1; i < originalH.length; ++i) {
36 const d = originalH[i] - originalH[i - 1];
37 if (originalH[i] > originalH[i - 1] && d > 0.5) {
38 correctedInputRange.push(inputRange[i]);
39 correctedInputRange.push(inputRange[i] + 0.00001);
40 correctedH.push(originalH[i] - 1);
41 correctedH.push(originalH[i]);
42 } else if (originalH[i] < originalH[i - 1] && d < -0.5) {
43 correctedInputRange.push(inputRange[i]);
44 correctedInputRange.push(inputRange[i] + 0.00001);
45 correctedH.push(originalH[i] + 1);
46 correctedH.push(originalH[i]);
47 } else {
48 correctedInputRange.push(inputRange[i]);
49 correctedH.push(originalH[i]);
50 }
51 }
52 h = (interpolate(value, correctedInputRange, correctedH, Extrapolation.CLAMP) + 1) % 1;
53 } else {
54 h = interpolate(value, inputRange, colors.h, Extrapolation.CLAMP);
55 }
56 const s = interpolate(value, inputRange, colors.s, Extrapolation.CLAMP);
57 const v = interpolate(value, inputRange, colors.v, Extrapolation.CLAMP);
58 const a = interpolate(value, inputRange, colors.a, Extrapolation.CLAMP);
59 return hsvToColor(h, s, v, a);
60};
61const toLinearSpace = (x, gamma) => {
62 'worklet';
63
64 return x.map(v => Math.pow(v / 255, gamma));
65};
66const toGammaSpace = (x, gamma) => {
67 'worklet';
68
69 return Math.round(Math.pow(x, 1 / gamma) * 255);
70};
71const interpolateColorsRGB = (value, inputRange, colors, options) => {
72 'worklet';
73
74 const {
75 gamma = 2.2
76 } = options;
77 let {
78 r: outputR,
79 g: outputG,
80 b: outputB
81 } = colors;
82 if (gamma !== 1) {
83 outputR = toLinearSpace(outputR, gamma);
84 outputG = toLinearSpace(outputG, gamma);
85 outputB = toLinearSpace(outputB, gamma);
86 }
87 const r = interpolate(value, inputRange, outputR, Extrapolation.CLAMP);
88 const g = interpolate(value, inputRange, outputG, Extrapolation.CLAMP);
89 const b = interpolate(value, inputRange, outputB, Extrapolation.CLAMP);
90 const a = interpolate(value, inputRange, colors.a, Extrapolation.CLAMP);
91 if (gamma === 1) {
92 return rgbaColor(r, g, b, a);
93 }
94 return rgbaColor(toGammaSpace(r, gamma), toGammaSpace(g, gamma), toGammaSpace(b, gamma), a);
95};
96const getInterpolateRGB = colors => {
97 'worklet';
98
99 const r = [];
100 const g = [];
101 const b = [];
102 const a = [];
103 for (let i = 0; i < colors.length; ++i) {
104 const color = colors[i];
105 const processedColor = processColor(color);
106 // explicit check in case if processedColor is 0
107 if (processedColor !== null && processedColor !== undefined) {
108 r.push(red(processedColor));
109 g.push(green(processedColor));
110 b.push(blue(processedColor));
111 a.push(opacity(processedColor));
112 }
113 }
114 return {
115 r,
116 g,
117 b,
118 a
119 };
120};
121const getInterpolateHSV = colors => {
122 'worklet';
123
124 const h = [];
125 const s = [];
126 const v = [];
127 const a = [];
128 for (let i = 0; i < colors.length; ++i) {
129 const color = colors[i];
130 const processedColor = processColor(color);
131 if (typeof processedColor === 'number') {
132 const processedHSVColor = RGBtoHSV(red(processedColor), green(processedColor), blue(processedColor));
133 h.push(processedHSVColor.h);
134 s.push(processedHSVColor.s);
135 v.push(processedHSVColor.v);
136 a.push(opacity(processedColor));
137 }
138 }
139 return {
140 h,
141 s,
142 v,
143 a
144 };
145};
146
147/**
148 * Lets you map a value from a range of numbers to a range of colors using
149 * linear interpolation.
150 *
151 * @param value - A number from the `input` range that is going to be mapped to
152 * the color in the `output` range.
153 * @param inputRange - An array of numbers specifying the input range of the
154 * interpolation.
155 * @param outputRange - An array of output colors values (eg. "red", "#00FFCC",
156 * "rgba(255, 0, 0, 0.5)").
157 * @param colorSpace - The color space to use for interpolation. Defaults to
158 * 'RGB'.
159 * @param options - Additional options for interpolation -
160 * {@link InterpolationOptions}.
161 * @returns The color after interpolation from within the output range in
162 * rgba(r, g, b, a) format.
163 * @see https://docs.swmansion.com/react-native-reanimated/docs/utilities/interpolateColor
164 */
165
166export function interpolateColor(value, inputRange, outputRange, colorSpace = 'RGB', options = {}) {
167 'worklet';
168
169 if (colorSpace === 'HSV') {
170 return interpolateColorsHSV(value, inputRange, getInterpolateHSV(outputRange), options);
171 } else if (colorSpace === 'RGB') {
172 return interpolateColorsRGB(value, inputRange, getInterpolateRGB(outputRange), options);
173 }
174 throw new ReanimatedError(`Invalid color space provided: ${colorSpace}. Supported values are: ['RGB', 'HSV'].`);
175}
176export let ColorSpace = /*#__PURE__*/function (ColorSpace) {
177 ColorSpace[ColorSpace["RGB"] = 0] = "RGB";
178 ColorSpace[ColorSpace["HSV"] = 1] = "HSV";
179 return ColorSpace;
180}({});
181export function useInterpolateConfig(inputRange, outputRange, colorSpace = ColorSpace.RGB, options = {}) {
182 return useSharedValue({
183 inputRange,
184 outputRange,
185 colorSpace,
186 cache: makeMutable(null),
187 options
188 });
189}
190//# sourceMappingURL=interpolateColor.js.map
\No newline at end of file