Search code examples
cssreactjstailwind-cssshadow

Set the color of shadow according to the theme of the image in inner-div


Is there a way to set the shadow color of a div based on the theme/color of the image inside the div?

For instance, if an image of a car driving on a forest road is used, the shadow color should be set according to the color of the image.

I haven't tried anything yet, but I'm open to suggestions. Creating a function to set the image as the div's background might allow the shadow color to access it somehow. I realize I might be completely off track, but I'm struggling to figure this out.

I'm using React.js and Tailwind CSS.


Solution

  • I recommend you check out the colotheif library.

    You can use this library to get the Dominant Color from the image and then use that color in your box shadow.

    Here is a demo of getting the dominant color: https://lokeshdhakar.com/projects/color-thief/

    Moreover, this is how your code might look like,

    const [dominantColor, setDominantColor] = useState(null);
    const imageUrl = 'https://th.bing.com/th/id/OIG3.ROpYc8LkzQdqXyRhWJc5?pid=ImgGn';
    
    useEffect(() => {
        const colorThief = new ColorThief();
    
        const fetchDominantColor = async () => {
            try {
                const response = await fetch(imageUrl);
                const blob = await response.blob();
    
                const img = new Image();
                img.crossOrigin = 'Anonymous';
    
                const imageUrlObject = URL.createObjectURL(blob);
    
                img.src = imageUrlObject;
    
                img.onload = function () {
                    const color = colorThief.getColor(img);
                    setDominantColor(color);
                };
    
                img.onerror = function (error) {
                    console.error('Error loading image:', error);
                };
            } catch (error) {
                console.error('Error fetching dominant color:', error);
            }
        };
    
        fetchDominantColor();
    
        return () => {
            URL.revokeObjectURL(imageUrl);
        };
    }, [imageUrl]);
    

    ...

    {dominantColor && (
        <img
            className="flex justify-center items-center size-44"
            style={{
                boxShadow: `0 0 20px 20px rgba(${dominantColor.join(',')}, 0.5)`
            }}
            src={imageUrl}
            alt="Dominant Color"
            width={100}
            height={100}
        />
    )}