Estoy haciendo una solicitud en mi proyecto de reacción para obtener svgs usando axios y obtengo los datos de svg como una cadena. ¿Cómo puedo cambiar todos los valores de fill de path en la cadena a un color específico?
Este es aproximadamente mi componente React:
export const ColorSvg = props => { const [ state, setState ] = React.useState({ svgData: undefined, }); React.useEffect(() => { if (!props.src) { return; } myAxiosGet(props.src) // my custom wrapper for axios .then(res => { if (res.ok) { // before converting to base64 I would like to change all path fill values to props.color const color = props.color; const base64data = btoa(unescape(encodeURIComponent(res.data))); setState(prevState => ({ ...prevState, svgData: base64data })); } }) }, [props.color, props.src]); return ( <> { state.svgData && <img height={props.height} width={props.width} src={`data:image/svg+xml;base64,${state.svgData}`} alt="" /> } </> ); }; Los datos de la string svg que recibo (es decir, res.data) son los siguientes:
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none"> <path fill-rule="evenodd" clip-rule="evenodd" d="M0.862154 9.414C0.0811059 8.63295 0.0811042 7.36662 0.862153 6.58557L1.95111 5.49661V3.95318C1.95111 2.84861 2.84654 1.95318 3.95111 1.95318H5.49454L6.58557 0.862154C7.36661 0.0811059 8.63295 0.0811042 9.41399 0.862153L10.505 1.95318H12.0452C13.1498 1.95318 14.0452 2.84861 14.0452 3.95318V5.4934L15.1374 6.58557C15.9185 7.36661 15.9185 8.63295 15.1374 9.41399L14.0452 10.5062V12.0473C14.0452 13.1519 13.1498 14.0473 12.0452 14.0473H10.5041L9.414 15.1374C8.63295 15.9185 7.36662 15.9185 6.58557 15.1374L5.49547 14.0473H3.95112C2.84655 14.0473 1.95111 13.1519 1.95111 12.0473V10.503L0.862154 9.414ZM7.73026 10.7313L12.016 6.73134L10.6513 5.26923L7.04794 8.6324L5.34931 7.04701L3.98467 8.50912L6.36563 10.7313L7.04794 11.3682L7.73026 10.7313Z" fill="#0EBC73"/> </svg> ¿Cómo puedo iterar sobre TODOS los elementos de la path y cambiar su valor de fill a props.color ? Me imagino que tendría que analizar la cadena en formato xml y luego iterar sobre todos los elementos y si el elemento es path y el fill existe, cámbielo a props.color , lo que puede ser innecesario tener que escribir desde cero en lugar de usar un paquete npm existente.
Esta respuesta apuntada por enxaneta trabaja. Todo lo que tengo que hacer es antes de la codificación base64 ejecutar la siguiente línea que reemplaza todo el fill de la path con un color específico:
const svgString = res.data; const colorisedSvgString = svgString.replace(/(?<=<path\b[^<>]*)\s*\bfill=(["']).*?\1/, ` fill="${props.color}"`); // now encode colorisedSvgStringPara reemplazar todas las ocurrencias use:
const colorisedSvgString = svgString.replaceAll(/(?<=<path\b[^<>]*)\s*\bfill=(["']).*?\1/g, ` fill="${color}"`); La expresión regular anterior también incluye "none" , que es posible que desee dejar sin cambios, en ese caso, lo siguiente debería funcionar para ignorar "none" :
const colorisedSvgString = svgString.replaceAll(/(?<=<path\b[^<>]*)\s*\bfill=(["'](?!none)).*?\1/g, ` fill="${color}"`);