Image-Based Color Theme Generator React JS Script

“We recently received an intriguing inquiry through our contact form from a developer seeking an innovative solution to automatically generate a dynamic color theme for their web application based on a featured image. The request was to create a script that would extract the dominant color of an image, calculate a contrasting text color, and adjust the background color accordingly. Inspired by this challenge, I’ve developed a custom React JavaScript script to achieve exactly that. In this post, I’ll walk through the code and explain how it works, providing a valuable resource for anyone looking to integrate dynamic color theming into their own projects.”

This React JavaScript script generates a dynamic color theme for a web application based on the dominant color of a featured image.

Key Features:

  1. Extracts the source URL of the featured image.
  2. Simulates an API call to retrieve the dominant color of the image (replace with an actual API call).
  3. Calculates a contrasting text color based on the dominant color.
  4. Adjusts the background color by generating a shade of the dominant color.
  5. Applies these colors to the application using CSS custom properties.
import React, { useState, useEffect } from 'react';

function App() {
  const [imageSrc, setImageSrc] = useState('');
  const [dominantColor, setDominantColor] = useState('');

  useEffect(() => {
    // Assuming the first featured image has an ID of 'featured-image'
    const image = document.getElementById('featured-image');

    if (image) {
      const imgSrc = image.getAttribute('src');
      setImageSrc(imgSrc);

      // Simulated API call to get dominant color (replace with actual API call)
      const getDominantColor = async () => {
        try {
          const response = await fetch(`https://example-api.com/image-color?url=${imgSrc}`);
          const data = await response.json();
          setDominantColor(data.dominantColor);
        } catch (error) {
          console.error('Error fetching dominant color:', error);
        }
      };

      getDominantColor();
    }
  }, []);

  useEffect(() => {
    if (dominantColor) {
      // Get the root element of the document
      const root = document.documentElement;

      // Set the text color based on the dominant color
      const textColor = getContrastingColor(dominantColor);
      root.style.setProperty('--text-color', textColor);

      // Set other color variables based on the dominant color
      const backgroundColor = getShade(dominantColor, -20);
      root.style.setProperty('--background-color', backgroundColor);

      // Apply other styles as needed
    }
  }, [dominantColor]);

  // Function to get contrasting color for text
  function getContrastingColor(color) {
    // Simulated logic to get contrasting color (replace with actual color contrast logic)
    const isDark = isColorDark(color);
    return isDark ? '#ffffff' : '#000000';
  }

  // Function to check if a color is dark
  function isColorDark(color) {
    // Simulated logic to check if a color is dark (replace with actual color brightness calculation)
    const brightness = getBrightness(color);
    return brightness < 128;
  }

  // Function to get brightness of a color
  function getBrightness(color) {
    // Simulated logic to get brightness of a color (replace with actual color brightness calculation)
    const [r, g, b] = color.match(/\d+/g).map(x => parseInt(x, 10));
    return (r * 299 + g * 587 + b * 114) / 1000;
  }

  // Function to get a shade of a color
  function getShade(color, shade) {
    // Simulated logic to get a shade of a color (replace with actual color shade calculation)
    const [r, g, b] = color.match(/\d+/g).map(x => parseInt(x, 10));
    const newR = Math.max(0, Math.min(255, r + (r * shade) / 100));
    const newG = Math.max(0, Math.min(255, g + (g * shade) / 100));
    const newB = Math.max(0, Math.min(255, b + (b * shade) / 100));
    return `rgb(${newR}, ${newG}, ${newB})`;
  }

  return (
    <div>
      <h1>Dynamic Color Theme</h1>
      <p>The text color and theme will change based on the dominant color of the first featured image.</p>
      <img id="featured-image" src={imageSrc} alt="Featured Image" />
    </div>
  );
}

export default App;

Step-by-Step Process:

  1. The script initializes state variables imageSrc and dominantColor using useState.
  2. The first useEffect hook retrieves the featured image’s source URL and simulates an API call to get the dominant color.
  3. The second useEffect hook updates the text color and background color based on the dominant color.
  4. Helper functions (getContrastingColor, isColorDark, getBrightness, and getShade) calculate color contrasts, darkness, brightness, and shades.

Example Usage:

To use this script, replace the simulated API call with an actual API endpoint that analyzes image colors. Then, integrate this component into your React application.

Notes:

  • This script assumes the featured image has an ID of ‘featured-image’.
  • The color calculation logic is simplified and may need refinement for production use.
  • Actual API calls and error handling should be implemented accordingly.

Please note that this script is a simplified example and may need adjustments based on your specific use case and requirements. It assumes the presence of a featured image with a specific ID and uses simulated functions for color manipulation and contrast calculation. In a real-world scenario, you would replace these simulated functions with actual color manipulation and contrast calculation libraries or APIs.

Related blog posts