Skip to content

Instantly share code, notes, and snippets.

@HebeHH
Created October 7, 2024 01:53
Show Gist options
  • Save HebeHH/a27cad60df5d70fb725b63e749a791b2 to your computer and use it in GitHub Desktop.
Save HebeHH/a27cad60df5d70fb725b63e749a791b2 to your computer and use it in GitHub Desktop.
React class to color an svg file on hover
"use client";
import React, { useState, useRef, useEffect } from "react";
interface HoverSVGProps {
src: string;
width: number;
height: number;
color: string;
alt: string;
hoverColor: string;
}
const HoverSVG: React.FC<HoverSVGProps> = ({
src,
width,
height,
color,
hoverColor,
}) => {
const [isHovered, setIsHovered] = useState(false);
const [uniqueId, setUniqueId] = useState("");
const componentRef = useRef<HTMLDivElement>(null);
useEffect(() => {
// Generate a unique ID when the component mounts
setUniqueId(`svg-filter-${Math.random().toString(36).substr(2, 9)}`);
}, []);
const handleMouseEnter = () => setIsHovered(true);
const handleMouseLeave = () => setIsHovered(false);
const currentColor = isHovered ? hoverColor : color;
return (
<div
ref={componentRef}
style={{ width, height }}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
<svg width={width} height={height}>
<defs>
<filter id={uniqueId}>
<feFlood floodColor={currentColor} result="flood" />
<feComposite
in="SourceGraphic"
in2="flood"
operator="arithmetic"
k1="1"
k2="0"
k3="0"
k4="0"
/>
</filter>
</defs>
<image
href={src}
width="100%"
height="100%"
preserveAspectRatio="xMidYMid meet"
filter={`url(#${uniqueId})`}
/>
</svg>
</div>
);
};
export default HoverSVG;
@HebeHH
Copy link
Author

HebeHH commented Oct 7, 2024

Usage

<HoverSVG
  alt="Twitter handle"
  src="/layout/twitter.svg"
  width={24}
  height={24}
  color="#37b7c3" // Normal color
  hoverColor="#ff204e" // Hover color
/>

Notes

  • Assumes svg file is white and will recolor from white
  • Alt text not working

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment