You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I want to refactor Q5.Color and the color function to add support for HDR colors, make oklch a new color mode, and remove HSB/HSV support.
p5 devs are planning to improve how color is handled in p5.js v2. I'd like them to take a look at my goals for the color improvements I will make in q5 v1.9.3. Hopefully some of these changes can be made in p5 as well! processing/p5.js#6680
What kind of magic is q5 using to achieve such results? q5 simply doesn't do any unnecessary color format conversions. Since the default color mode is RGB, q5 simply stores the user's rgb values as properties in a object.
But in p5, the user's legacy rgb 0-255 range input is converted to modern 0-1 range rgba values, both of which are stored in arrays. maxes arrays for each color format are also copied into every color object, which seems unnecessary. hsba and hsla are both defined on the object as null, even if the user doesn't intended to convert the color.
Make color components easier to view and edit
If you view a p5.Color in the console, you'll probably be confused by the output! Especially if you're a beginner programmer.
But in p5 these functions should've only been implemented for backwards compatibility. Thankfully color.setRed() and similar functions were introduced, but why not a color.getRed() or better yet expose the color components as public properties?
To improve q5 I'm taking inspiration from the popular JS color library culori represents colors as objects with letter properties, using a single color mode per object, making them easy to view and edit.
// culori.js rgba color data representation{r: 255,g: 10,b: 82,a: 1,mode: 'rgba'}
oklch support
But just making red, green, and blue components easier to edit doesn't fix the more fundamental problems with the RGB format. As noted in the article "OKLCH in CSS: why we moved from RGB and HSL":
"RGB, hex and color(display-p3) aren’t convenient for color modifications because, for the vast majority of humans, it’s difficult to intuitively set colors by changing the amount of red, blue and green. Further, RGB and hex also can’t encode P3 colors."
I recommend reading the full article, it's great! I'm going to make separate classes for rgb and oklch that extend Q5.Color, so that instanceof p5.Color checks can still work.
Currently Q5.Color instances internally output color to ctx.fillStyle or ctx.strokeStyle via their toString method. For Q5.ColorRGBA and Q5.ColorOKLCH their toString() functions won't require any calculations.
Auto-upgrade RGB to HDR
While I do think oklch is the future, I don't really expect any Intro to Web Design class/section to teach oklch anytime soon. But I want to get people using HDR colors today!
I think the best way to do this is to create a backwards compatibility class, Q5.ColorRGBA_P3. Users can still edit colors using the default RGB colorMode but the resulting colors will be internally mapped directly to the HDR "display-p3" color space in toString using this format: color(display-p3 r g b / a). https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color
To prevent toString from needing to do the format conversion from the legacy 0-255 range to the modern 0-1 range whenever toString is used, I'll create getter/setter properties for the purpose of watching for changes. Only when the color is changed will toString do new calculations.
Let users make colors using new Color()
p5.Color is not a class that belongs to a p5 instance but rather p5 itself. q5 mimics this implementation.
Yet,_colorMode is an instance variable, so it can't be accessed directly by the p5.Color constructor. p5 gets around it by passing p5 instances to the p5.Color constructor. Additionally, in q5 I'll need to access the canvas to get the canvas' color space. In q5, all of the color parsing code is done in the q5 instance level color function. I will maintain this structure.
Depending on the instance's current color mode and canvas color space, the q5 instance variable $.Color will be set to Q5.ColorRGBA, Q5.ColorRGBA_P3, or Q5.ColorOKLCH. These constructors will have no parsing overhead.
Remove HSB/HSV support
Support for the HSV color format will be removed in q5 v1.9.3 because it was rarely used, the amount of code required to convert between RGB and HSV was quite large, and color experts considered HSV to be flawed and outdated way back in 1997!
I want to refactor
Q5.Color
and thecolor
function to add support for HDR colors, make oklch a new color mode, and remove HSB/HSV support.p5 devs are planning to improve how color is handled in p5.js v2. I'd like them to take a look at my goals for the color improvements I will make in q5 v1.9.3. Hopefully some of these changes can be made in p5 as well!
processing/p5.js#6680
@limzykenneth @lindapaiste @Vishal2002 @JustZambetti @davepagurek @hellonearthis @meodai
Maintain good performance
q5 is 11x faster than p5 at creating 10,000 random colors: 3ms vs 33ms.
What kind of magic is q5 using to achieve such results? q5 simply doesn't do any unnecessary color format conversions. Since the default color mode is RGB, q5 simply stores the user's rgb values as properties in a object.
But in p5, the user's legacy rgb 0-255 range input is converted to modern 0-1 range rgba values, both of which are stored in arrays.
maxes
arrays for each color format are also copied into every color object, which seems unnecessary.hsba
andhsla
are both defined on the object as null, even if the user doesn't intended to convert the color.Make color components easier to view and edit
If you view a
p5.Color
in the console, you'll probably be confused by the output! Especially if you're a beginner programmer.To try to understand why
p5.Color
was implemented this way, we have to study its grandaddy: Processing.In Java Processing, the
color
method generated a primitiveint
, not an Object, and in Java ints can't have properties or methods. That's why thered
,green
,blue
,alpha
functions were necessary. Those individual color components could only be retrieved from a color int through bitwise operations, not via properties.https://forum.processing.org/two/discussion/15923/how-to-change-alpha-without-changing-the-whole-color.html
But in p5 these functions should've only been implemented for backwards compatibility. Thankfully
color.setRed()
and similar functions were introduced, but why not acolor.getRed()
or better yet expose the color components as public properties?To improve q5 I'm taking inspiration from the popular JS color library
culori
represents colors as objects with letter properties, using a single color mode per object, making them easy to view and edit.oklch support
But just making red, green, and blue components easier to edit doesn't fix the more fundamental problems with the RGB format. As noted in the article "OKLCH in CSS: why we moved from RGB and HSL":
"RGB, hex and color(display-p3) aren’t convenient for color modifications because, for the vast majority of humans, it’s difficult to intuitively set colors by changing the amount of red, blue and green. Further, RGB and hex also can’t encode P3 colors."
I recommend reading the full article, it's great! I'm going to make separate classes for rgb and oklch that extend
Q5.Color
, so thatinstanceof p5.Color
checks can still work.Currently
Q5.Color
instances internally output color toctx.fillStyle
orctx.strokeStyle
via theirtoString
method. ForQ5.ColorRGBA
andQ5.ColorOKLCH
theirtoString()
functions won't require any calculations.Auto-upgrade RGB to HDR
While I do think oklch is the future, I don't really expect any Intro to Web Design class/section to teach oklch anytime soon. But I want to get people using HDR colors today!
I think the best way to do this is to create a backwards compatibility class,
Q5.ColorRGBA_P3
. Users can still edit colors using the default RGBcolorMode
but the resulting colors will be internally mapped directly to the HDR "display-p3" color space intoString
using this format:color(display-p3 r g b / a)
.https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color
To prevent
toString
from needing to do the format conversion from the legacy 0-255 range to the modern 0-1 range whenevertoString
is used, I'll create getter/setter properties for the purpose of watching for changes. Only when the color is changed willtoString
do new calculations.Let users make colors using
new Color()
p5.Color
is not a class that belongs to a p5 instance but rather p5 itself. q5 mimics this implementation.Yet,
_colorMode
is an instance variable, so it can't be accessed directly by thep5.Color
constructor. p5 gets around it by passing p5 instances to thep5.Color
constructor. Additionally, in q5 I'll need to access thecanvas
to get the canvas' color space. In q5, all of the color parsing code is done in the q5 instance levelcolor
function. I will maintain this structure.Depending on the instance's current color mode and canvas color space, the q5 instance variable
$.Color
will be set toQ5.ColorRGBA
,Q5.ColorRGBA_P3
, orQ5.ColorOKLCH
. These constructors will have no parsing overhead.Remove HSB/HSV support
Support for the HSV color format will be removed in q5 v1.9.3 because it was rarely used, the amount of code required to convert between RGB and HSV was quite large, and color experts considered HSV to be flawed and outdated way back in 1997!
https://en.wikipedia.org/wiki/HSL_and_HSV#Disadvantages
The text was updated successfully, but these errors were encountered: