Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

143
Vistas
React IconTint (canvas) change color dynamically

Is there a way to change colors on <IconTint /> element from react-icon-tint library dynamically? I need the color to be changed on isActive state change but looks like it's not working as I expected because it uses canvas element under the hood.

I also tried to rerender the whole element on isActive change like that

{
  isActive ? (
    <IconTint src={getCustomIcon()} color={icon} />
  ) : (
    <IconTint src={getCustomIcon()} color={iconOnBackground} />
  );
}

But it also did not work.

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

I have looked at the source code, because it is a memoized component, it does not rerender on parent rerender, and because inside the useEffect that is used inside the component, dependencies like color and image src is not included, it does not rerender on prop change, obviously it is a bug, or an unwanted behaviour. I don't know why your way of doing it does not work, because those two IconTint components are two different components!. but you can do it this way:

 {isActive && <IconTint src={getCustomIcon()} color='#0000ff' />}
 {!isActive && <IconTint src={getCustomIcon()} color='#b43285' />}

I don't think this is performant, the source code is so simple, so you can implement IconTint inside your project and just add dependencies inside useEffect dependency array. Here I provided modified version.

import React, { memo, useEffect, useRef, useState } from "react";
import PropTypes from "prop-types";

const IconTint = ({ fallback = <span />, src, color, maxWidth, maxHeight }) => {
  const canvasRef = useRef(null);
  const [size, setSize] = useState({});

  const _scaleImage = (srcWidth, srcHeight, maxWidth, maxHeight) => {
    if (maxWidth && maxHeight) {
      const ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
      return { width: srcWidth * ratio, height: srcHeight * ratio };
    }
    if ((maxWidth && !maxHeight) || (!maxWidth && maxHeight)) {
      throw new Error(
        "If you are going to provide width, make sure to provide height as well"
      );
    }
    return { width: srcWidth, height: srcHeight };
  };

  useEffect(() => {
    const canvas = canvasRef.current;
    // eslint-disable-next-line no-undef
    const pic = new Image();
    pic.src = src;
    const tintCanvas = document.createElement("canvas");
    const tintCtx = tintCanvas.getContext("2d");
    const ctx = canvas.getContext("2d");
    pic.onload = () => {
      const result = _scaleImage(pic.width, pic.height, maxWidth, maxHeight);
      setSize(result);
      tintCanvas.width = result.width;
      tintCanvas.height = result.height;
      tintCtx.fillStyle = color;
      tintCtx.fillRect(0, 0, result.width, result.height);
      tintCtx.globalCompositeOperation = "destination-atop";
      tintCtx.drawImage(pic, 0, 0, result.width, result.height);
      ctx.globalAlpha = 1;
      ctx.drawImage(tintCanvas, 0, 0, result.width, result.height);
    };
  }, [src,color,maxHeight,maxWidth]);

  if (
    typeof window !== "undefined" &&
    window.document &&
    window.document.createElement
  ) {
    return <canvas width={size.width} height={size.height} ref={canvasRef} />;
  }
  return fallback;
};

IconTint.propTypes = {
  src: PropTypes.string.isRequired,
  color: PropTypes.string.isRequired,
  fallback: PropTypes.node,
  maxWidth: PropTypes.number,
  maxHeight: PropTypes.number
};

export default memo(IconTint);

now you can use this modified version like this:

<IconTint src={getCustomIcon()} color={isActive ? '#0000ff' : "#b43285"}/>
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda