Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

147
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda