-
-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
color()
not working with the hex notation when used before setup()
#348
Comments
Thanks for reporting this! Incidentally, the "hex converter" code correctly converts the hex code to the proper value -13312, but then that value is passed to the real Processing public final int color(float fgray) {
if (g == null) {
int gray = (int) fgray;
if (gray > 255) gray = 255; else if (gray < 0) gray = 0;
return 0xff000000 | (gray << 16) | (gray << 8) | gray;
}
return g.color(fgray);
} When this is called before the Sketch starts, the The fix here is for |
Here's where I am now. This code: ca = py5.color(255, 204, 0)
cb = py5.color("#FFCC00")
def setup():
py5.size(200, 200)
cc = py5.color(255, 204, 0)
cd = py5.color("#ffcc00")
py5.println(ca)
py5.println(cb)
py5.println(cc)
py5.println(cd)
py5.color_mode(py5.HSB, 360, 100, 100)
py5.println(ca)
py5.println(cb)
py5.println(cc)
py5.println(cd)
py5.println(ca.to_hex())
py5.println(cb.to_hex())
py5.println(cc.to_hex())
py5.println(cd.to_hex()) yields this output: (red=255, green=204, blue=0, alpha=255)
(red=255, green=204, blue=0, alpha=255)
(red=255, green=204, blue=0, alpha=255)
(red=255, green=204, blue=0, alpha=255)
(hue=48.000004, saturation=100.000000, brightness=100.000000, alpha=255.000000)
(hue=48.000004, saturation=100.000000, brightness=100.000000, alpha=255.000000)
(hue=48.000004, saturation=100.000000, brightness=100.000000, alpha=255.000000)
(hue=48.000004, saturation=100.000000, brightness=100.000000, alpha=255.000000)
#FFFFCC00
#FFFFCC00
#FFFFCC00
#FFFFCC00 Each Py5Color object needs to know the color mode settings and is therefore eternally linked to its creator. I didn't format the output to be something like I need to add intelligent rounding to those floats. The |
#FFFFCC00
#FFFFCC00
#FFFFCC00
#FFFFCC00 I just noticed these 8 character hex values are wrong. It should be |
Looks wonderful! What if the color objects displayed always the same representation, irrespective of the color mode? I admit I kind of like the idea of having valid Python on the |
After thinking about it some more, I see my original logic is flawed; currently the Py5Shape and Py5Graphics classes have repr strings with Py5Shape and Py5Graphics in them, but you create those instances with calls to
At first I thought, yes of course, let's do it, but then I realized it can't work that way because it would have to guess at the value ranges. If it is set to |
Here's what Processing does: colorMode(RGB, 255, 255, 255);
color c = color(255, 0, 1);
println(hue(c), saturation(c), brightness(c));
println(red(c), green(c), blue(c));
colorMode(HSB, 360, 100, 100);
println(hue(c), saturation(c), brightness(c));
println(red(c), green(c), blue(c)); 254.83333 255.0 255.0
255.0 0.0 1.0
359.7647 100.0 100.0
360.0 0.0 0.3921569 So Processing assumes the value ranges for the other color mode are identical to the active color mode...I don't like that all, but from looking at the code I understand why this happens. I'd much prefer for assumptions about the other color mode to not jump around like that. |
Silly idea but, let's see... how about adding a I was even wondering if to make the repr shorter it could be like: |
No, I can't do that. The Py5Color instances need to be created from the For the
Py5Color(red=255, green=204, blue=0, alpha=255)
Py5Color(hue=300, saturation=80, brightness=80, alpha=255) Maybe we could make it like this to include the ranges: Py5Color(red=255/255, green=204/255, blue=0/255, alpha=255/255)
Py5Color(hue=300/360, saturation=80/100, brightness=80/100, alpha=255/255) That seems a bit cluttered to me though, but it is an idea.
Py5Color(red=255, green=204, blue=0, alpha=255, hue=300°, saturation=80%, brightness=80%)
Py5Color(hue=300, saturation=80, brightness=80, alpha=255, red=100%, green=80%, blue=0%) To me this doesn't have any miscommunication about what is happening and it provides a complete set of information.
"#FFCC00FF" or Py5Color("#FFCC00FF") This seems a bit boring and also assumes the users are familiar with hex values. Graphic designers and people with html dev experience would be comfortable with this but many will not. Which do you like best? I kind of like the second one the best. It is easy to implement and would be helpful for folks debugging their code. That's the most important goal here. I do like your other ideas though about providing users with more functionality for working with colors. Earlier today I was thinking of adding other properties and methods to Py5Color but then I felt like I might be re-inventing the wheel and that there might already be a good Python color library out there. Turns out, there is: colour. Check it out, I think you might like it. It can already do everything we have been talking about. The color ranges are always [0, 1] so there is no ambiguity there. It would be easy for py5 to accept the colour library's Color class objects in addition to the current range of options (integers, hex strings, etc). |
Yeah! 1 or 2 would be great. I think I like 1 best, with the ranges. |
Here's where this is now. For RGB color mode with the ranges all set to the default and most common values 0-255, the Py5Color int will display this: Py5Color(red=255, green=204, blue=0, alpha=255, hue=48°, saturation=100%, brightness=100%) Observe that the RGB values come first and that there is no need for decimals. The HSB values have no user specified ranges so it will use 0-360° (degrees) for hue and 0-100% for saturation and brightness. This seemed to be the most common way to communicate HSB color params and it is also the most clear, with the For HSB color modes with the ranges set to 0-360 for hue and 0-100 for the others, the HSB values come first. The RGB values use percentages, indicating that is is some fraction of an unspecified range. Py5Color(hue=48°, saturation=100%, brightness=100%, alpha=100%, red=100%, green=80%, blue=0%) For non-traditional color ranges it will display color values as floats with 2 decimal places. I don't think it is really necessary to specifically include what the ranges are because the user will know what the color ranges are from their call to Py5Color(red=100.00, green=80.00, blue=0.00, alpha=100.00, hue=48°, saturation=100%, brightness=100%)
Py5Color(hue=6.67, saturation=10.00, brightness=10.00, alpha=10.00, red=100%, green=80%, blue=0%) There's also the All of this seems straightforward to me and great for debugging. Certainly easier than those large negative numbers folks have somehow gotten used to. In addition, I have the Python colour library now working great with py5. I can use the colour library's Color class and seamlessly pass it to py5 color methods: from colour import Color
color1 = Color("violet")
def setup():
py5.size(200, 200)
py5.rect(0, 0, 100, 100)
py5.fill(color1, 128)
py5.rect(50, 50, 100, 100)
py5.run_sketch() |
Looks great! Two things to consider...
|
Good point, including the range is useful for debugging purposes. And since this feature's only real purpose is for debugging color related code, I added it back in. The strings are getting a bit long for my taste, but that's fine, it does look neatly organized. Py5Color(RGB, red=126/255, green=129/255, blue=6/255, alpha=255/255, hue=61.46/360, saturation=95.35/100, brightness=50.59/100)
Py5Color(HSB, hue=61.46/360, saturation=95.35/100, brightness=50.59/100, alpha=100.00/100, red=126/255, green=129/255, blue=6/255) I got rid of the percentages and degrees stuff for HSB because it looked bad when along side other value/range pairs. This is consistent and clear. For RGB values, when the ranges are all [0, 255] it does not use decimals because they are not necessary. For all other cases, there are 2 decimals for the values. In RGB color mode, the HSB values are presented with ranges are 360, 100, 100. In HSB color mode, the RGB values are presented with ranges 255, 255, 255.
All image or drawing programs like Inkscape, Krita, Gimp, etc that I've seen always use a 360 range for hue and 100 range for saturation and brightness. This also makes the most sense if you think about hue as a color wheel. Processing uses 255 for HSB because both HSB and RGB use the same shared color mode variables. There's no need for py5 to duplicate that design choice. |
I made some minor cosmetic improvements and made the code more robust. Now the printed colors look like this: Py5Color(RGB, red=165/255, green=42/255, blue=42/255, alpha=255/255, hue=0/360, saturation=74.55/100, brightness=64.71/100)
Py5Color(HSB, hue=0/360, saturation=74.55/100, brightness=64.71/100, alpha=255/255, red=165/255, green=42/255, blue=42/255) I think it looks neatly organized and is certainly much better than the large negative numbers. I got rid of the The Python colour library works great with py5 and is a full-featured Color class library. You can pass it to any method that requires a color of some kind. In addition, py5 already supports all named colors known to matplotlib. That was great but it required you to know the names of the colors, which was too much for my brain to handle. I added the names to a submodule so you can now write code like this: py5.fill(py5.xkcd_colors.WEIRD_GREEN)
py5.stroke(py5.css4_colors.PALEGOLDENROD) And as always, Imported mode users can omit the If you have an editor that supports tab completion, you will no longer need to remember the names of any colors. |
WOW! This colormap feature seems amazing! I was fiddling with some "color indexation" a while ago, this might make things much easier!!! |
Thanks! This is very different from the features in other tools that are available, and maybe it would even be a great way to teach color maps to students. |
I think I'm done implementing the code changes for this. The new CMAP colormode stuff will only be available to |
Fantastic. We should add this information about availability, or a link to it, at the Sketch.color_mode(), Py5Graphics.color_mode() and Py5Shape.color_mode() documentation pages! |
I'm still working on this, but about to make a PR and close it. This is now working code: import matplotlib as mpl
from colour import Color
import py5
from py5 import css4_colors, mpl_cmaps, xkcd_colors
# color palette, all of these values can be passed to any py5 method that needs a color
violet = py5.color("violet")
bisque = py5.color(css4_colors.BISQUE)
green = Color("green")
purple = py5.color("#FF00FF")
print(violet)
print(bisque)
print(green)
print(purple)
def setup():
py5.size(400, 600, py5.P2D)
py5.color_mode(py5.CMAP, mpl_cmaps.OCEAN, py5.width, py5.height)
def draw():
# make the background color oscillate over time
py5.background(py5.remap(py5.sin(py5.frame_count * 0.02), -1, 1, 0, py5.width))
for _ in range(250):
x = py5.random(py5.width)
y = py5.random(py5.height)
py5.fill(x, y)
py5.rect(x, y, 10, 10)
py5.run_sketch() I added While testing this I discovered it is now easy to make colors oscillate.
Yes, documenting it is another can of worms. There is another open issue about gaps in the color documentation and I will bundle that with this. |
Now this is closed. Thank you, @villares , for the conversation that sparked all these good ideas! |
ca
, created beforesetup()
, should matchcb
andcc
.The text was updated successfully, but these errors were encountered: