Skip to content

Commit a19995f

Browse files
authored
Merge pull request #7676 from limzykenneth/dev-2.0
[p5.js 2.0] Restore single color value define grayscale color
2 parents 8d90c3d + 8315204 commit a19995f

File tree

2 files changed

+107
-7
lines changed

2 files changed

+107
-7
lines changed

src/color/p5.Color.js

Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,23 @@ class Color {
4444

4545
static colorMap = {};
4646
static #colorjsMaxes = {};
47+
static #grayscaleMap = {};
4748

4849
// Used to add additional color modes to p5.js
4950
// Uses underlying library's definition
5051
static addColorMode(mode, definition){
5152
ColorSpace.register(definition);
5253
Color.colorMap[mode] = definition.id;
54+
5355
// Get colorjs maxes
5456
Color.#colorjsMaxes[mode] = Object.values(definition.coords).reduce((acc, v) => {
5557
acc.push(v.refRange || v.range);
5658
return acc;
5759
}, []);
5860
Color.#colorjsMaxes[mode].push([0, 1]);
61+
62+
// Get grayscale mapping
63+
Color.#grayscaleMap[mode] = definition.fromGray;
5964
}
6065

6166
constructor(vals, colorMode, colorMaxes) {
@@ -99,15 +104,38 @@ class Color {
99104
let mappedVals;
100105

101106
if(colorMaxes){
107+
// NOTE: need to consider different number of arguments (eg. CMYK)
102108
if(vals.length === 4){
103109
mappedVals = Color.mapColorRange(vals, this.mode, colorMaxes);
104110
}else if(vals.length === 3){
105111
mappedVals = Color.mapColorRange([vals[0], vals[1], vals[2]], this.mode, colorMaxes);
106112
mappedVals.push(1);
107113
}else if(vals.length === 2){
108-
mappedVals = Color.mapColorRange([vals[0], vals[0], vals[0], vals[1]], this.mode, colorMaxes);
114+
// Grayscale with alpha
115+
if(Color.#grayscaleMap[this.mode]){
116+
mappedVals = Color.#grayscaleMap[this.mode](vals[0], colorMaxes);
117+
}else{
118+
mappedVals = Color.mapColorRange([vals[0], vals[0], vals[0]], this.mode, colorMaxes);
119+
}
120+
const alphaMaxes = Array.isArray(colorMaxes[colorMaxes.length-1]) ?
121+
colorMaxes[colorMaxes.length-1] :
122+
[0, colorMaxes[colorMaxes.length-1]];
123+
mappedVals.push(
124+
map(
125+
vals[1],
126+
alphaMaxes[0],
127+
alphaMaxes[1],
128+
0,
129+
1
130+
)
131+
);
109132
}else if(vals.length === 1){
110-
mappedVals = Color.mapColorRange([vals[0], vals[0], vals[0]], this.mode, colorMaxes);
133+
// Grayscale only
134+
if(Color.#grayscaleMap[this.mode]){
135+
mappedVals = Color.#grayscaleMap[this.mode](vals[0], colorMaxes);
136+
}else{
137+
mappedVals = Color.mapColorRange([vals[0], vals[0], vals[0]], this.mode, colorMaxes);
138+
}
111139
mappedVals.push(1);
112140
}else{
113141
throw new Error('Invalid color');
@@ -652,6 +680,78 @@ function color(p5, fn, lifecycles){
652680
*/
653681
p5.Color = Color;
654682

683+
sRGB.fromGray = P3.fromGray = function(val, maxes){
684+
// Use blue max
685+
const p5Maxes = maxes.map((max) => {
686+
if(!Array.isArray(max)){
687+
return [0, max];
688+
}else{
689+
return max;
690+
}
691+
});
692+
693+
const v = map(val, p5Maxes[2][0], p5Maxes[2][1], 0, 1);
694+
return [v, v, v];
695+
};
696+
697+
HSBSpace.fromGray = HSLSpace.fromGray = function(val, maxes){
698+
// Use brightness max
699+
const p5Maxes = maxes.map((max) => {
700+
if(!Array.isArray(max)){
701+
return [0, max];
702+
}else{
703+
return max;
704+
}
705+
});
706+
707+
const v = map(val, p5Maxes[2][0], p5Maxes[2][1], 0, 100);
708+
return [0, 0, v];
709+
};
710+
711+
HWBSpace.fromGray = function(val, maxes){
712+
// Use Whiteness and Blackness to create number line
713+
const p5Maxes = maxes.map((max) => {
714+
if(!Array.isArray(max)){
715+
return [0, max];
716+
}else{
717+
return max;
718+
}
719+
});
720+
721+
const wbMax =
722+
(Math.abs(p5Maxes[1][0] - p5Maxes[1][1])) / 2 +
723+
(Math.abs(p5Maxes[2][0] - p5Maxes[2][1])) / 2;
724+
725+
const nVal = map(val, 0, wbMax, 0, 100);
726+
let white, black;
727+
if(nVal < 50){
728+
black = nVal;
729+
white = 100 - nVal;
730+
}else if(nVal >= 50){
731+
white = nVal;
732+
black = 100 - nVal;
733+
}
734+
return [0, white, black];
735+
};
736+
737+
Lab.fromGray =
738+
LCHSpace.fromGray =
739+
OKLab.fromGray =
740+
OKLCHSpace.fromGray =
741+
function(val, maxes){
742+
// Use lightness max
743+
const p5Maxes = maxes.map((max) => {
744+
if(!Array.isArray(max)){
745+
return [0, max];
746+
}else{
747+
return max;
748+
}
749+
});
750+
751+
const v = map(val, p5Maxes[0][0], p5Maxes[0][1], 0, 100);
752+
return [v, 0, 0];
753+
};
754+
655755
// Register color modes and initialize Color maxes to what p5 has set for itself
656756
p5.Color.addColorMode(RGB, sRGB);
657757
p5.Color.addColorMode(RGBHDR, P3);

test/unit/color/p5.Color.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -737,8 +737,8 @@ suite('p5.Color', function() {
737737
assert.instanceOf(c, Color);
738738
});
739739

740-
test('should correctly set RGB levels', function() {
741-
assert.deepEqual(c._color.coords, [39.3, 39.3, 39.3]);
740+
test('should correctly set color coordinates', function() {
741+
assert.deepEqual(c._color.coords, [0, 0, 39.3]);
742742
assert.equal(c._color.alpha, 1);
743743
});
744744
});
@@ -754,7 +754,7 @@ suite('p5.Color', function() {
754754
});
755755

756756
test('should correctly set RGB levels', function() {
757-
assert.deepEqual(c._color.coords, [39.3, 39.3, 39.3]);
757+
assert.deepEqual(c._color.coords, [0, 0, 39.3]);
758758
assert.equal(c._color.alpha, 0.275);
759759
});
760760
});
@@ -770,7 +770,7 @@ suite('p5.Color', function() {
770770
});
771771

772772
test('should correctly set RGB levels', function() {
773-
assert.deepEqual(c._color.coords, [39.3, 39.3, 39.3]);
773+
assert.deepEqual(c._color.coords, [0, 0, 39.3]);
774774
assert.equal(c._color.alpha, 1);
775775
});
776776
});
@@ -786,7 +786,7 @@ suite('p5.Color', function() {
786786
});
787787

788788
test('should correctly set RGB levels', function() {
789-
assert.deepEqual(c._color.coords, [39.3, 39.3, 39.3]);
789+
assert.deepEqual(c._color.coords, [0, 0, 39.3]);
790790
assert.equal(c._color.alpha, 0.275);
791791
});
792792
});

0 commit comments

Comments
 (0)