Skip to content
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

[p5.js 2.0]: Color module rewrite - Culori.js #7374

Draft
wants to merge 13 commits into
base: dev-2.0
Choose a base branch
from
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"acorn": "^8.12.1",
"acorn-walk": "^8.3.4",
"colorjs.io": "^0.5.2",
"culori": "^4.0.1",
"file-saver": "^1.3.8",
"gifenc": "^1.0.3",
"libtess": "^1.2.2",
Expand Down Expand Up @@ -84,4 +85,4 @@
"pre-commit": "lint-staged"
}
}
}
}
89 changes: 52 additions & 37 deletions preview/index.html
Original file line number Diff line number Diff line change
@@ -1,41 +1,56 @@
<!DOCTYPE html>
<html>

<head>
<title>P5 test</title>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta charset="utf-8">

<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>

<body>
<script type="module">
import p5 from '../src/app.js';

const sketch = function (p) {
p.setup = function () {
p.createCanvas(200, 200);
<head>
<title>P5 test</title>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache" />
<meta charset="utf-8" />

<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>

<body>
<script type="module">
import p5 from "../src/app.js";

const sketch = function (p) {
p.setup = function () {
p.createCanvas(600, 600);
p.background(50);
//p.colorMode('hsl');
// Create a p5.Color object using HSL values.
let c = p.color('rgb(0, 10, 75)');

// Draw the left rectangle.
p.noStroke();
p.fill(c);
p.rect(15, 15, 35, 70);

// Set 'lightValue' to 75.
let satValue = p.saturation(c);
console.log("This is the 's' value", satValue)

// Draw the right rectangle.
//p.colorMode('rgb')
p.fill(255, satValue, 50);
p.rect(50, 15, 35, 70);
};

p.draw = function () {
// Create a p5.Color object using RGB values
//p.fill('hsb(160, 100%, 50%)'); //hsb seems to be having issues to render
p.textSize(50);
p.text("hello", 200, 80);
// The background goes from white to red to green to blue fill
};
};

p.draw = function () {
p.background(0, 50, 50);
p.circle(100, 100, 50);

p.fill('white');
p.textSize(30);
p.text('hello', 10, 30);
};
};

new p5(sketch);
</script>
</body>

</html>
new p5(sketch);
</script>
</body>
</html>
171 changes: 129 additions & 42 deletions src/color/creating_reading.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
* @requires constants
*/

import './p5.Color';
import { range } from 'colorjs.io/fn';
import "./p5.Color";
import { range } from "colorjs.io/fn";
import { interpolate, parse, converter } from "culori";

function creatingReading(p5, fn){
function creatingReading(p5, fn) {
/**
* Gets the alpha (transparency) value of a color.
*
Expand Down Expand Up @@ -106,8 +107,8 @@ function creatingReading(p5, fn){
* </code>
* </div>
*/
fn.alpha = function(c) {
p5._validateParameters('alpha', arguments);
fn.alpha = function (c) {
p5._validateParameters("alpha", arguments);
return this.color(c)._getAlpha();
};

Expand Down Expand Up @@ -242,8 +243,8 @@ function creatingReading(p5, fn){
* </code>
* </div>
*/
fn.blue = function(c) {
p5._validateParameters('blue', arguments);
fn.blue = function (c) {
p5._validateParameters("blue", arguments);
return this.color(c)._getBlue();
};

Expand Down Expand Up @@ -387,8 +388,8 @@ function creatingReading(p5, fn){
* </code>
* </div>
*/
fn.brightness = function(c) {
p5._validateParameters('brightness', arguments);
fn.brightness = function (c) {
p5._validateParameters("brightness", arguments);
return this.color(c)._getBrightness();
};

Expand Down Expand Up @@ -676,8 +677,8 @@ function creatingReading(p5, fn){
* @param {p5.Color} color
* @return {p5.Color}
*/
fn.color = function(...args) {
p5._validateParameters('color', args);
fn.color = function (...args) {
p5._validateParameters("color", args);
if (args[0] instanceof p5.Color) {
return args[0]; // Do nothing if argument is already a color object.
}
Expand Down Expand Up @@ -817,8 +818,8 @@ function creatingReading(p5, fn){
* </code>
* </div>
*/
fn.green = function(c) {
p5._validateParameters('green', arguments);
fn.green = function (c) {
p5._validateParameters("green", arguments);
return this.color(c)._getGreen();
};

Expand Down Expand Up @@ -938,8 +939,8 @@ function creatingReading(p5, fn){
* </code>
* </div>
*/
fn.hue = function(c) {
p5._validateParameters('hue', arguments);
fn.hue = function (c) {
p5._validateParameters("hue", arguments);
return this.color(c)._getHue();
};

Expand Down Expand Up @@ -1002,34 +1003,120 @@ function creatingReading(p5, fn){
* </code>
* </div>
*/
fn.lerpColor = function(c1, c2, amt) {
p5._validateParameters('lerpColor', arguments);

// Find the closest common ancestor color space
let spaceIndex = -1;
while(
(
spaceIndex+1 < c1.color.space.path.length ||
spaceIndex+1 < c2.color.space.path.length
) &&
c1.color.space.path[spaceIndex+1] === c2.color.space.path[spaceIndex+1]
){
spaceIndex += 1;
}
// fn.lerpColor = function(c1, c2, amt) {
// p5._validateParameters('lerpColor', arguments);

// // Find the closest common ancestor color space
// let spaceIndex = -1;
// while(
// (
// spaceIndex+1 < c1.color.space.path.length ||
// spaceIndex+1 < c2.color.space.path.length
// ) &&
// c1.color.space.path[spaceIndex+1] === c2.color.space.path[spaceIndex+1]
// ){
// spaceIndex += 1;
// }

// if (spaceIndex === -1) {
// // This probably will not occur in practice
// throw new Error('Cannot lerp colors. No common color space found');
// }

// // Get lerp value as a color in the common ancestor color space
// const lerpColor = range(c1.color, c2.color, {
// space: c1.color.space.path[spaceIndex].id
// })(amt);

// return new p5.Color(lerpColor, this._colorMode, this._colorMaxes);
// };

fn.lerpColor = function (c1, c2, amt) {
p5._validateParameters("lerpColor", arguments);

// Check if both colors are in the same color space
const mode1 = c1.color.mode;
console.log("ColorMode 1 is:", mode1);
const mode2 = c2.color.mode;
console.log("ColorMode 2 is:", mode2);

let interpolator;

if (spaceIndex === -1) {
// This probably will not occur in practice
throw new Error('Cannot lerp colors. No common color space found');
if (mode1 === mode2) {
// If they are in the same color space, interpolate directly in that space
interpolator = interpolate([c1.color, c2.color], mode1);
} else {
// If not in the same space, convert `c2` to `c1`'s color space for interpolation
const convertedC2 = converter(mode1)(c2.color);
interpolator = interpolate([c1.color, convertedC2], mode1);
}

// Get lerp value as a color in the common ancestor color space
const lerpColor = range(c1.color, c2.color, {
space: c1.color.space.path[spaceIndex].id
})(amt);
// Interpolate the color based on amt
const lerpColor = interpolator(amt);

// Return the new p5.Color object with the interpolated color
return new p5.Color(lerpColor, this._colorMode, this._colorMaxes);
};

/**
* Blends multiple colors to find a color between them.
*
* The `amt` parameter specifies the amount to interpolate between the color
* stops which are colors at each `amt` value "location" with `amt` values
* that are between 2 color stops interpolating between them based on its relative
* distance to both.
*
* The way that colors are interpolated depends on the current
* <a href="#/colorMode">colorMode()</a>.
*
* @method paletteLerp
* @param {[p5.Color, Number][]} colors_stops color stops to interpolate from
* @param {Number} amt number to use to interpolate relative to color stops
* @return {p5.Color} interpolated color.
*
* @example
* <div>
* <code>
* function setup() {
* createCanvas(400, 400);
* }
*
* function draw() {
* // The background goes from white to red to green to blue fill
* background(paletteLerp([
* ['white', 0],
* ['red', 0.05],
* ['green', 0.25],
* ['blue', 1]
* ], millis() / 10000 % 1));
* }
* </code>
* </div>
*/

fn.paletteLerp = function (color_stops, amt) {
const first_color_stop = color_stops[0];
console.log ("This is first color stop", first_color_stop);

if (amt < first_color_stop[1])
return this.color(first_color_stop[0]);

for (let i = 1; i < color_stops.length; i++) {
const color_stop = color_stops[i];
if (amt < color_stop[1]) {
const prev_color_stop = color_stops[i - 1];
return this.lerpColor(
this.color(prev_color_stop[0]),
this.color(color_stop[0]),
(amt - prev_color_stop[1]) / (color_stop[1] - prev_color_stop[1])
);
}
}

return this.color(color_stops[color_stops.length - 1][0]);
};

/**
* Gets the lightness value of a color.
*
Expand Down Expand Up @@ -1170,8 +1257,8 @@ function creatingReading(p5, fn){
* </code>
* </div>
*/
fn.lightness = function(c) {
p5._validateParameters('lightness', arguments);
fn.lightness = function (c) {
p5._validateParameters("lightness", arguments);
return this.color(c)._getLightness();
};

Expand Down Expand Up @@ -1306,8 +1393,8 @@ function creatingReading(p5, fn){
* </code>
* </div>
*/
fn.red = function(c) {
p5._validateParameters('red', arguments);
fn.red = function (c) {
p5._validateParameters("red", arguments);
return this.color(c)._getRed();
};

Expand Down Expand Up @@ -1483,14 +1570,14 @@ function creatingReading(p5, fn){
* </code>
* </div>
*/
fn.saturation = function(c) {
p5._validateParameters('saturation', arguments);
fn.saturation = function (c) {
p5._validateParameters("saturation", arguments);
return this.color(c)._getSaturation();
};
}

export default creatingReading;

if(typeof p5 !== 'undefined'){
if (typeof p5 !== "undefined") {
creatingReading(p5, p5.prototype);
}
Loading