react-native-reanimated
Version:
More powerful alternative to Animated library for React Native.
43 lines (35 loc) • 1.45 kB
text/typescript
;
import { logger, type ValueProcessor } from '../../../../common';
import type { CSSGradientStop } from '../../../types';
import { processColorSVG } from './colors';
import { processPercentage } from './percentage';
type ProcessedGradientStop = number | string | false;
const NO_STOPS_WARNING = 'No stops in SVG gradient';
export const processSVGGradientStops = ((stops) => {
if (!stops || !Array.isArray(stops) || stops.length === 0) {
logger.warn(NO_STOPS_WARNING);
return [];
}
const intermediate = stops.map((stop) => {
const rawColor = stop.color && processColorSVG(stop.color);
const stopOpacity = processPercentage(stop.opacity ?? 1);
const finalColor =
typeof rawColor === 'number' && typeof stopOpacity === 'number'
? ((Math.round(((rawColor >>> 24) & 0xff) * stopOpacity) << 24) |
(rawColor & 0x00ffffff)) >>>
0
: rawColor;
return {
offset: processPercentage(stop.offset ?? 0),
color: finalColor,
};
}) as { offset: number; color: number | false | string }[];
intermediate.sort((a, b) => Number(a.offset) - Number(b.offset));
// This linearised format is used to be consistent with what RNSVG does
const ret: ProcessedGradientStop[] = [];
for (const item of intermediate) {
ret.push(item.offset);
ret.push(item.color);
}
return ret;
}) satisfies ValueProcessor<CSSGradientStop[], ProcessedGradientStop[]>;