Saturday, February 8, 2025

Full Color Spectrum Color Chart / ColorPicker

For a project I have been working on with ESP32, I wanted to make a simple drawing program. It would be simple enough to add a limited swatch of colors, but I really wanted to provide as many colors as would be supported by the hardware. 

Being that my input controls are limited (it is not a touch screen), I wanted to have all the (spectrum) colors available on one chart. After looking around for a bit, and playing around with DeepSeek, I was able to quickly produce the chart I was looking for, and it's actually pretty simple. 




The answer is that by using two gradients (one horizontal, one vertical) with drawing on a html Canvas element, would produce this result. Here is the HTML if you want to try it yourself. 


     <canvas id="paletteCanvas" width="500" height="300"></canvas>


    <script>
        // Function to initialize the color palette
        function initPalette() {
            const canvas = document.getElementById("paletteCanvas");
            const ctx = canvas.getContext("2d");

            // Create horizontal gradient (hues)
            const horizontalGradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
            horizontalGradient.addColorStop(0, "rgb(255, 255, 255)"); // White
            horizontalGradient.addColorStop(0.1, "rgb(255, 0, 0)"); // Red
            horizontalGradient.addColorStop(0.25, "rgb(255, 0, 255)"); // Magenta
            horizontalGradient.addColorStop(0.4, "rgb(0, 0, 255)"); // Blue
            horizontalGradient.addColorStop(0.55, "rgb(0, 255, 255)"); // Cyan
            horizontalGradient.addColorStop(0.7, "rgb(0, 255, 0)"); // Green
            horizontalGradient.addColorStop(0.85, "rgb(255, 255, 0)"); // Yellow
            horizontalGradient.addColorStop(1, "rgb(255, 0, 0)"); // Red

            // Apply horizontal gradient to the canvas
            ctx.fillStyle = horizontalGradient;
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            // Create vertical gradient (brightness)
            const verticalGradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
            verticalGradient.addColorStop(0, "rgba(255, 255, 255, 1)"); // White (opaque)
            verticalGradient.addColorStop(0.5, "rgba(255, 255, 255, 0)"); // Transparent
            verticalGradient.addColorStop(0.5, "rgba(0, 0, 0, 0)"); // Transparent
            verticalGradient.addColorStop(1, "rgba(0, 0, 0, 1)"); // Black (opaque)

            // Apply vertical gradient to the canvas
            ctx.fillStyle = verticalGradient;
            ctx.fillRect(0, 0, canvas.width, canvas.height);
        }

        // Initialize the palette when the page loads
        window.onload = initPalette;
    </script>


I also replicated this in Photoshop using 2 gradients stacked, and the result is a bit nicer, having less of that start effect in the middle. 



No comments: