import React, { useMemo } from 'react'; import { StyleSheet, View } from 'react-native'; import { AppColors } from '../constants/Colors'; interface ThemeBackdropProps { colors: AppColors; } const texturePoints = [ [4, 6, 2], [12, 14, 1], [20, 9, 2], [26, 19, 1], [34, 8, 2], [42, 16, 1], [50, 10, 1], [58, 18, 2], [66, 7, 1], [74, 15, 2], [82, 11, 1], [90, 17, 2], [8, 30, 1], [16, 25, 2], [24, 33, 1], [32, 27, 2], [40, 35, 1], [48, 28, 2], [56, 36, 1], [64, 26, 2], [72, 34, 1], [80, 29, 2], [88, 37, 1], [94, 31, 2], [6, 48, 2], [14, 44, 1], [22, 52, 2], [30, 46, 1], [38, 54, 2], [46, 49, 1], [54, 56, 2], [62, 45, 1], [70, 53, 2], [78, 47, 1], [86, 55, 2], [92, 50, 1], [10, 70, 1], [18, 64, 2], [26, 72, 1], [34, 67, 2], [42, 74, 1], [50, 68, 2], [58, 76, 1], [66, 65, 2], [74, 73, 1], [82, 69, 2], [90, 77, 1], [96, 71, 2], ]; const parseColor = (value: string) => { if (value.startsWith('#')) { const cleaned = value.replace('#', ''); const normalized = cleaned.length === 3 ? cleaned.split('').map((c) => `${c}${c}`).join('') : cleaned; const int = Number.parseInt(normalized, 16); return { r: (int >> 16) & 255, g: (int >> 8) & 255, b: int & 255, a: 1, }; } const match = value.match(/rgba?\(([^)]+)\)/i); if (!match) return { r: 0, g: 0, b: 0, a: 0 }; const parts = match[1].split(',').map((part) => part.trim()); return { r: Number.parseFloat(parts[0]) || 0, g: Number.parseFloat(parts[1]) || 0, b: Number.parseFloat(parts[2]) || 0, a: parts.length > 3 ? Number.parseFloat(parts[3]) || 0 : 1, }; }; const mixColor = (start: string, end: string, ratio: number) => { const a = parseColor(start); const b = parseColor(end); const t = Math.max(0, Math.min(1, ratio)); const r = Math.round(a.r + (b.r - a.r) * t); const g = Math.round(a.g + (b.g - a.g) * t); const bl = Math.round(a.b + (b.b - a.b) * t); const alpha = a.a + (b.a - a.a) * t; return `rgba(${r}, ${g}, ${bl}, ${alpha})`; }; const ThemeBackdropInner: React.FC = ({ colors }) => { const gradientStrips = useMemo(() => Array.from({ length: 18 }).map((_, index, arr) => { const ratio = index / (arr.length - 1); return mixColor(colors.pageGradientStart, colors.pageGradientEnd, ratio); }), [colors.pageGradientStart, colors.pageGradientEnd]); return ( {gradientStrips.map((stripColor, index) => ( ))} {texturePoints.map(([x, y, size], index) => ( ))} ); }; export const ThemeBackdrop = React.memo(ThemeBackdropInner); const styles = StyleSheet.create({ gradientLayer: { ...StyleSheet.absoluteFillObject }, gradientStrip: { flex: 1 }, textureLayer: { ...StyleSheet.absoluteFillObject, }, noiseDot: { position: 'absolute', }, });