UNPKG

react-native-svg

Version:
78 lines (68 loc) 2.12 kB
import React, { Children } from 'react'; import extractColor from './extractColor'; import extractOpacity from './extractOpacity'; import extractTransform from './extractTransform'; import units from '../units'; const percentReg = /^([+\-]?\d+(?:\.\d+)?(?:[eE][+\-]?\d+)?)(%?)$/; function percentToFloat(percent) { if (typeof percent === 'number') { return percent; } if ( typeof percent === 'object' && typeof percent.__getAnimatedValue === 'function' ) { return percent.__getAnimatedValue(); } const matched = typeof percent === 'string' && percent.match(percentReg); if (!matched) { console.warn(`"${percent}" is not a valid number or percentage string.`); return 0; } return matched[2] ? matched[1] / 100 : +matched[1]; } const offsetComparator = (object, other) => object[0] - other[0]; export default function extractGradient(props, parent) { const { id, children, gradientTransform, transform, gradientUnits } = props; if (!id) { return null; } const stops = []; const childArray = Children.map(children, child => React.cloneElement(child, { parent, }), ); const l = childArray.length; for (let i = 0; i < l; i++) { const { props: { offset, stopColor, stopOpacity }, } = childArray[i]; const offsetNumber = percentToFloat(offset || 0); const color = stopColor && extractColor(stopColor); if (typeof color !== 'number' || isNaN(offsetNumber)) { console.warn( `"${stopColor}" is not a valid color or "${offset}" is not a valid offset`, ); continue; } const alpha = Math.round(extractOpacity(stopOpacity) * 255); stops.push([offsetNumber, (color & 0x00ffffff) | (alpha << 24)]); } stops.sort(offsetComparator); const gradient = []; const k = stops.length; for (let j = 0; j < k; j++) { const s = stops[j]; gradient.push(s[0], s[1]); } return { name: id, gradient, children: childArray, gradientUnits: units[gradientUnits] || 0, gradientTransform: extractTransform( gradientTransform || transform || props, ), }; }