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\$
2
  • \$\begingroup\$ Just improve my code. \$\endgroup\$ Commented Jul 27, 2014 at 0:29
  • \$\begingroup\$ If I redraw it, It become a bit laggy. \$\endgroup\$ Commented Jul 27, 2014 at 0:30

2 Answers 2

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\$
0
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 and acknowledge you have read our privacy policy.

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