react-native-animated-glow
Version:
A performant, highly-customizable animated glow effect for React Native, powered by Skia and Reanimated.
145 lines (144 loc) • 6.17 kB
JavaScript
// src/animated-glow/helpers.ts
Object.defineProperty(exports, "__esModule", { value: true });
exports.interpolateColorArrayWorklet = exports.interpolateNumberArray = exports.interpolateRgbaWorklet = exports.interpolateNumber = exports.getGlowSizeVec4Worklet = exports.getGradientColorWorklet = exports.interpolateColorWorklet = exports.parseColorToRgbaWorklet = exports.parseColorToRgbWorklet = void 0;
// --- Worklet to parse hex/rgb color strings ---
const parseColorToRgbWorklet = (color) => {
'worklet';
const rgbaMatch = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
if (rgbaMatch) {
return { r: parseInt(rgbaMatch[1], 10), g: parseInt(rgbaMatch[2], 10), b: parseInt(rgbaMatch[3], 10) };
}
let hex = color.startsWith('#') ? color.substring(1) : color;
if (hex.length === 3)
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
if (hex.length === 6) {
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
return { r, g, b };
}
return { r: 0, g: 0, b: 0 }; // Default to black if parsing fails
};
exports.parseColorToRgbWorklet = parseColorToRgbWorklet;
// --- Worklet to parse full RGBA color strings ---
const parseColorToRgbaWorklet = (color) => {
'worklet';
if (!color || color === 'transparent') {
return { r: 0, g: 0, b: 0, a: 0 };
}
const rgbaMatch = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
if (rgbaMatch) {
return {
r: parseInt(rgbaMatch[1], 10),
g: parseInt(rgbaMatch[2], 10),
b: parseInt(rgbaMatch[3], 10),
a: rgbaMatch[4] !== undefined ? parseFloat(rgbaMatch[4]) : 1.0
};
}
let hex = color.startsWith('#') ? color.substring(1) : color;
if (hex.length === 3)
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
if (hex.length === 8) { // RRGGBBAA
return { r: parseInt(hex.substring(0, 2), 16), g: parseInt(hex.substring(2, 4), 16), b: parseInt(hex.substring(4, 6), 16), a: parseInt(hex.substring(6, 8), 16) / 255 };
}
if (hex.length === 6) { // RRGGBB
return { r: parseInt(hex.substring(0, 2), 16), g: parseInt(hex.substring(2, 4), 16), b: parseInt(hex.substring(4, 6), 16), a: 1.0 };
}
return { r: 0, g: 0, b: 0, a: 0 }; // Default to transparent black
};
exports.parseColorToRgbaWorklet = parseColorToRgbaWorklet;
const interpolateColorWorklet = (color1, color2, factor) => {
'worklet';
if (!color1 || !color2) {
return color1 || color2 || { r: 0, g: 0, b: 0 };
}
const r = Math.round(color1.r + factor * (color2.r - color1.r));
const g = Math.round(color1.g + factor * (color2.g - color1.g));
const b = Math.round(color1.b + factor * (color2.b - color1.b));
return { r, g, b };
};
exports.interpolateColorWorklet = interpolateColorWorklet;
const getGradientColorWorklet = (progress, colors) => {
'worklet';
if (!colors || colors.length === 0)
return { r: 0, g: 0, b: 0 };
if (colors.length === 1)
return colors[0];
const fullColorList = [...colors, colors[0]];
const segLen = 1 / (fullColorList.length - 1);
const segIdx = Math.min(Math.floor(progress / segLen), fullColorList.length - 2);
const segProg = (progress - segIdx * segLen) / segLen;
return (0, exports.interpolateColorWorklet)(fullColorList[segIdx], fullColorList[segIdx + 1], segProg);
};
exports.getGradientColorWorklet = getGradientColorWorklet;
const getGlowSizeVec4Worklet = (glowSize) => {
'worklet';
const arr = Array.isArray(glowSize) ? glowSize : [glowSize];
if (arr.length === 0)
return [0, 0, 0, 0];
if (arr.length === 1)
return [arr[0], arr[0], arr[0], arr[0]];
if (arr.length === 2)
return [arr[0], arr[1], arr[1], arr[0]];
if (arr.length === 3)
return [arr[0], arr[1], arr[2], arr[2]];
return [arr[0], arr[1], arr[2], arr[3]];
};
exports.getGlowSizeVec4Worklet = getGlowSizeVec4Worklet;
const interpolateNumber = (from, to, p) => {
'worklet';
return from + (to - from) * p;
};
exports.interpolateNumber = interpolateNumber;
const interpolateRgbaWorklet = (c1, c2, p) => {
'worklet';
const r = Math.round(c1.r + p * (c2.r - c1.r));
const g = Math.round(c1.g + p * (c2.g - c1.g));
const b = Math.round(c1.b + p * (c2.b - c1.b));
const a = c1.a + p * (c2.a - c1.a);
return { r, g, b, a };
};
exports.interpolateRgbaWorklet = interpolateRgbaWorklet;
const interpolateNumberArray = (from, to, p) => {
'worklet';
const fromLen = from.length;
const toLen = to.length;
if (fromLen === 0 && toLen === 0)
return [];
if (toLen === 0)
return from.map(v => (0, exports.interpolateNumber)(v, 0, p));
if (fromLen === 0)
return to.map(v => (0, exports.interpolateNumber)(0, v, p));
const maxLen = Math.max(fromLen, toLen);
const result = new Array(maxLen);
for (let i = 0; i < maxLen; i++) {
const fromVal = from[i] ?? from[fromLen - 1];
const toVal = to[i] ?? to[toLen - 1];
result[i] = (0, exports.interpolateNumber)(fromVal, toVal, p);
}
return result;
};
exports.interpolateNumberArray = interpolateNumberArray;
const interpolateColorArrayWorklet = (from, to, p) => {
'worklet';
const fromLen = from.length;
const toLen = to.length;
if (fromLen === 0 && toLen === 0)
return [];
const fromRgb = from.map(c => (0, exports.parseColorToRgbWorklet)(c));
const toRgb = to.map(c => (0, exports.parseColorToRgbWorklet)(c));
if (toLen === 0)
return fromRgb;
if (fromLen === 0)
return toRgb;
const maxLen = Math.max(fromLen, toLen);
const result = [];
for (let i = 0; i < maxLen; i++) {
const fromColor = fromRgb[i] ?? fromRgb[fromRgb.length - 1];
const toColor = toRgb[i] ?? toRgb[toRgb.length - 1];
result.push((0, exports.interpolateColorWorklet)(fromColor, toColor, p));
}
return result;
};
exports.interpolateColorArrayWorklet = interpolateColorArrayWorklet;
;