4
\$\begingroup\$

I'm trying to improve my Color Picker code. It works like Photoshop and I don't want to use a library.

    for(var yColor = 0; yColor < 255; yColor++)
    {
        var r = 255,
            g = 0,
            b = 0;
        for(var xColor = 0; xColor < 255; xColor++)
        {
            if(r == 255 && g < 255 && b == 0) g += 6;
            else if(r > 0 && g == 255 && b == 0) r -= 6;
            else if(r == 0 && g == 255 && b < 255) b += 6;
            else if(r == 0 && g > 0 && b == 255) g -= 6;
            else if(r < 255 && g == 0 && b == 255) r += 6;
            else if(r == 255 && g == 0 && b > 0) b -= 6;

            if(r > 255) r = 255;
            else if(r < 0) r = 0;
            else if(g > 255) g = 255;
            else if(g < 0) g = 0;
            else if(b > 255) b = 255;
            else if(b < 0) b = 0;

            var rG = r + yColor > 255 ? 255 : r + yColor;
            var gG = g + yColor > 255 ? 255 : g + yColor;
            var bG = b + yColor > 255 ? 255 : b + yColor;

            GAContext.beginPath();
            GAContext.fillStyle = "rgb(" + rG + ", " + gG + ", " + bG + ")";
            GAContext.rect(xColor, yColor, 1, 1);
            GAContext.fill();
        }
    }
\$\endgroup\$
  • \$\begingroup\$ Just improve my code. \$\endgroup\$ – Lukas Häring Jul 27 '14 at 0:29
  • \$\begingroup\$ If I redraw it, It become a bit laggy. \$\endgroup\$ – Lukas Häring Jul 27 '14 at 0:30
5
\$\begingroup\$

The way you check the bounds of r, g, b is a bit repetitive:

if(r > 255) r = 255;
else if(r < 0) r = 0;
else if(g > 255) g = 255;
else if(g < 0) g = 0;
else if(b > 255) b = 255;
else if(b < 0) b = 0;

You could use a helper function to simplify a bit:

function ensureBounds(x) {
    return Math.min(255, Math.max(0, x));  // Thanks @flambino!
}

r = ensureBounds(r);
g = ensureBounds(g);
b = ensureBounds(b);

And you could reuse it later to simplify setting rG, and the other:

var rG = ensureBounds(r + yColor);
var gG = ensureBounds(g + yColor);
var bG = ensureBounds(b + yColor);

UPDATE

This was my earlier version of the ensureBounds function, before I adopted @flambino's suggestion above:

function ensureBounds(x) {
    if (x > 255) return 255;
    if (x < 0) return 0;
    return x;
}
\$\endgroup\$
5
\$\begingroup\$

If I redraw it, It become a bit laggy.

In my tests, using createImageData and putImageData to fill the individual pixels ran about 3x faster than rect and fill.

You can replace this code:

GAContext.beginPath();
GAContext.fillStyle = "rgb(" + rG + ", " + gG + ", " + bG + ")";
GAContext.rect(xColor, yColor, 1, 1);
GAContext.fill();

With this:

pixelData[0] = rG;
pixelData[1] = gG;
pixelData[2] = bG;
GAContext.putImageData(pixel, xColor, yColor);

And before the loop, add this:

var pixel = GAContext.createImageData(1, 1);
var pixelData = pixel.data;
pixelData[3] = 255;

Test it out here. This Stack Overflow question is relevant. You may also be able to figure out a clever way to do this with gradients that would be much faster.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.