diff --git a/src/math/calculation.js b/src/math/calculation.js
index 82b788e788..785695a410 100644
--- a/src/math/calculation.js
+++ b/src/math/calculation.js
@@ -12,11 +12,7 @@ function calculation(p5, fn){
* -5 and 5 are both five units away from zero, so calling `abs(-5)` and
* `abs(5)` both return 5. The absolute value of a number is always positive.
*
- * @method abs
- * @param {Number} n number to compute.
- * @return {Number} absolute value of given number.
- *
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -36,6 +32,55 @@ function calculation(p5, fn){
* // from the middle.
* rect(0, 100 - h, 100, h);
* }
+ * ```
+ *
+ * `abs()` can also be used in shaders with p5.strands. The following example
+ * uses `abs()` to create a mirror effect on the color of a shape.
+ *
+ * ```js example
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ * myShader = buildColorShader(shaderCallback);
+ * describe('A sphere with colors that fold back like a mirror.');
+ * }
+ *
+ * function shaderCallback() {
+ * // shaderCallback runs on the GPU. millis() gives ms since start; multiply by 0.001 for seconds.
+ * let t = millis() * 0.001;
+ *
+ * // sin(t) goes between -1 and 1 over time.
+ * let sinVal = sin(t);
+ *
+ * // abs() folds the negative values to positive.
+ * // Now value goes between 0 and 1, creating a mirror effect.
+ * let value = abs(sinVal);
+ *
+ * // Each color is [R, G, B, A] with values from 0 to 1.
+ * let navy = [0.2, 0.2, 0.8, 1];
+ * let coral = [0.8, 0.2, 0.2, 1];
+ *
+ * finalColor.begin();
+ *
+ * // mix() blends between navy (when value = 0) and coral (when value = 1).
+ * finalColor.set(mix(navy, coral, value));
+ *
+ * finalColor.end();
+ * }
+ *
+ * function draw() {
+ * background(220);
+ * shader(myShader);
+ * noStroke();
+ * sphere(30);
+ * }
+ * ```
+ *
+ * @method abs
+ * @param {Number} n number to compute.
+ * @return {Number} absolute value of given number.
+ *
*/
fn.abs = Math.abs;
@@ -46,11 +91,7 @@ function calculation(p5, fn){
* For example, calling `ceil(9.03)` and `ceil(9.97)` both return the value
* 10.
*
- * @method ceil
- * @param {Number} n number to round up.
- * @return {Integer} rounded up number.
- *
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -75,6 +116,57 @@ function calculation(p5, fn){
*
* describe('Two rectangles. The one on the left is dark red and the one on the right is bright red.');
* }
+ * ```
+ *
+ * `ceil()` can also be used in shaders with p5.strands. The following example
+ * uses `ceil()` to create a stepped color effect on a shape.
+ *
+ * ```js example
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ * myShader = buildColorShader(shaderCallback);
+ * describe('A sphere with stepped color bands.');
+ * }
+ *
+ * function shaderCallback() {
+ * // shaderCallback runs on the GPU. millis() gives ms since start; multiply by 0.001 for seconds.
+ * let t = millis() * 0.001;
+ *
+ * // sin(t) goes between -1 and 1.
+ * // 0.5 + 0.5 * sin(t) remaps this to the 0 to 1 range.
+ * let sinVal = 0.5 + 0.5 * sin(t);
+ *
+ * // Multiply by 4 then ceil to get the next whole number up.
+ * // Divide by 4 to bring the result back to the 0 to 1 range.
+ * // This creates 4 distinct stepped color levels: 0.25, 0.5, 0.75, 1.
+ * let value = ceil(sinVal * 4) / 4;
+ *
+ * // Each color is [R, G, B, A] with values from 0 to 1.
+ * let cyan = [0, 0.5, 1, 1];
+ * let orange = [1, 0.5, 0, 1];
+ *
+ * finalColor.begin();
+ *
+ * // mix() blends between cyan (when value = 0) and orange (when value = 1).
+ * // ceil() creates sharp steps between color levels.
+ * finalColor.set(mix(cyan, orange, value));
+ *
+ * finalColor.end();
+ * }
+ *
+ * function draw() {
+ * background(220);
+ * shader(myShader);
+ * noStroke();
+ * sphere(30);
+ * }
+ * ```
+ *
+ * @method ceil
+ * @param {Number} n number to round up.
+ * @return {Integer} rounded up number.
*/
fn.ceil = Math.ceil;
@@ -212,11 +304,7 @@ function calculation(p5, fn){
* Calculates the value of Euler's number e (2.71828...) raised to the power
* of a number.
*
- * @method exp
- * @param {Number} n exponent to raise.
- * @return {Number} e^n
- *
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -240,8 +328,9 @@ function calculation(p5, fn){
*
* describe('A series of circles that grow exponentially from top left to bottom right.');
* }
+ * ```
*
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -262,6 +351,53 @@ function calculation(p5, fn){
* // Draw a point.
* point(x, y);
* }
+ * ```
+ *
+ * `exp()` can also be used in shaders with p5.strands. The following example
+ * uses `exp()` to create an accelerating color transition on a shape.
+ *
+ * ```js example
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ * myShader = buildColorShader(shaderCallback);
+ * describe('A sphere that brightens with accelerating speed.');
+ * }
+ *
+ * function shaderCallback() {
+ * // shaderCallback runs on the GPU. millis() gives ms since start; multiply by 0.0005 to slow it.
+ * let t = millis() * 0.0005;
+ *
+ * // exp(t) grows slowly at first, then accelerates (exponential growth).
+ * // Multiply by 0.01 to keep it from growing too fast.
+ * // min(..., 1) caps the value at 1 so it doesn't go past white.
+ * let value = min(exp(t) * 0.01, 1);
+ *
+ * // Each color is [R, G, B, A] with values from 0 to 1.
+ * let darkBlue = [0.1, 0.1, 0.3, 1];
+ * let lightYellow = [1, 1, 0.5, 1];
+ *
+ * finalColor.begin();
+ *
+ * // mix() blends between darkBlue (when value = 0) and lightYellow (when value = 1).
+ * // Because exp() accelerates, the color transition gets faster over time.
+ * finalColor.set(mix(darkBlue, lightYellow, value));
+ *
+ * finalColor.end();
+ * }
+ *
+ * function draw() {
+ * background(220);
+ * shader(myShader);
+ * noStroke();
+ * sphere(30);
+ * }
+ * ```
+ *
+ * @method exp
+ * @param {Number} n exponent to raise.
+ * @return {Number} e^n
*/
fn.exp = Math.exp;
@@ -269,11 +405,7 @@ function calculation(p5, fn){
* Calculates the closest integer value that is less than or equal to the
* value of a number.
*
- * @method floor
- * @param {Number} n number to round down.
- * @return {Integer} rounded down number.
- *
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -296,6 +428,57 @@ function calculation(p5, fn){
*
* describe('Two rectangles. The one on the left is bright red and the one on the right is black.');
* }
+ * ```
+ *
+ * `floor()` can also be used in shaders with p5.strands. The following example
+ * uses `floor()` to create banding effects on a shape.
+ *
+ * ```js example
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ * myShader = buildColorShader(shaderCallback);
+ * describe('A sphere with posterized color bands.');
+ * }
+ *
+ * function shaderCallback() {
+ * // shaderCallback runs on the GPU. millis() gives ms since start; multiply by 0.001 for seconds.
+ * let t = millis() * 0.001;
+ *
+ * // sin(t) goes between -1 and 1.
+ * // 0.5 + 0.5 * sin(t) remaps this to the 0 to 1 range.
+ * let sinVal = 0.5 + 0.5 * sin(t);
+ *
+ * // Multiply by 4 then floor to get the next whole number down.
+ * // Divide by 4 to bring the result back to the 0 to 1 range.
+ * // This creates 5 distinct stepped color levels: 0, 0.25, 0.5, 0.75, 1.
+ * let value = floor(sinVal * 4) / 4;
+ *
+ * // Each color is [R, G, B, A] with values from 0 to 1.
+ * let darkPurple = [0.2, 0, 0.8, 1];
+ * let brightTeal = [0.2, 1, 0.8, 1];
+ *
+ * finalColor.begin();
+ *
+ * // mix() blends between darkPurple (when value = 0) and brightTeal (when value = 1).
+ * // The floor() creates visible banding/posterization in the color.
+ * finalColor.set(mix(darkPurple, brightTeal, value));
+ *
+ * finalColor.end();
+ * }
+ *
+ * function draw() {
+ * background(220);
+ * shader(myShader);
+ * noStroke();
+ * sphere(30);
+ * }
+ * ```
+ *
+ * @method floor
+ * @param {Number} n number to round down.
+ * @return {Integer} rounded down number.
*/
fn.floor = Math.floor;
@@ -312,13 +495,7 @@ function calculation(p5, fn){
* number outside of the original interval. For example, calling
* `lerp(0, 10, 1.5)` will return 15.
*
- * @method lerp
- * @param {Number} start first value.
- * @param {Number} stop second value.
- * @param {Number} amt number.
- * @return {Number} lerped value.
- *
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -346,8 +523,9 @@ function calculation(p5, fn){
*
* describe('Five points in a horizontal line. The outer points are black and the inner points are gray.');
* }
+ * ```
*
- * @example
+ * ```js example
* let x = 50;
* let y = 50;
* let targetX = 50;
@@ -377,6 +555,55 @@ function calculation(p5, fn){
* x = mouseX;
* y = mouseY;
* }
+ * ```
+ *
+ * `lerp()` can also be used in shaders with p5.strands, where it maps to the
+ * mix() function in GLSL. The following example uses
+ * mix() to blend colors on a shape over time.
+ *
+ * ```js example
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ * myShader = buildColorShader(shaderCallback);
+ * describe('A sphere that blends between teal and coral.');
+ * }
+ *
+ * function shaderCallback() {
+ * // shaderCallback runs on the GPU. millis() gives ms since start; multiply by 0.001 for seconds.
+ * let t = millis() * 0.001;
+ *
+ * // sin(t) goes between -1 and 1 over time.
+ * // 0.5 + 0.5 * sin(t) remaps this to the 0 to 1 range.
+ * let value = 0.5 + 0.5 * sin(t);
+ *
+ * // Each color is [R, G, B, A] with values from 0 to 1.
+ * let teal = [0, 0.8, 0.8, 1];
+ * let coral = [1, 0.5, 0.3, 1];
+ *
+ * finalColor.begin();
+ *
+ * // In p5.strands, lerp() maps to the GLSL mix() function.
+ * // mix() blends teal (when value = 0) and coral (when value = 1).
+ * finalColor.set(mix(teal, coral, value));
+ *
+ * finalColor.end();
+ * }
+ *
+ * function draw() {
+ * background(220);
+ * shader(myShader);
+ * noStroke();
+ * sphere(30);
+ * }
+ * ```
+ *
+ * @method lerp
+ * @param {Number} start first value.
+ * @param {Number} stop second value.
+ * @param {Number} amt number.
+ * @return {Number} lerped value.
*/
fn.lerp = function(start, stop, amt) {
// p5._validateParameters('lerp', arguments);
@@ -389,11 +616,7 @@ function calculation(p5, fn){
* `log()` expects the `n` parameter to be a value greater than 0 because
* the natural logarithm is defined that way.
*
- * @method log
- * @param {Number} n number greater than 0.
- * @return {Number} natural logarithm of n.
- *
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -409,8 +632,9 @@ function calculation(p5, fn){
*
* describe('Two white circles. The circle at the top-left is small. The circle at the bottom-right is about five times larger.');
* }
+ * ```
*
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -431,6 +655,55 @@ function calculation(p5, fn){
* // Draw a point.
* point(x, y);
* }
+ * ```
+ *
+ * `log()` can also be used in shaders with p5.strands. The following example
+ * uses `log()` to create a decelerating color transition on a shape.
+ *
+ * ```js example
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ * myShader = buildColorShader(shaderCallback);
+ * describe('A sphere that slowly shifts from purple to yellow.');
+ * }
+ *
+ * function shaderCallback() {
+ * // shaderCallback runs on the GPU. millis() gives ms since start; multiply by 0.001 for seconds.
+ * let t = millis() * 0.001;
+ *
+ * // log(1 + t) grows quickly at first, then slows down over time.
+ * // Add 1 so we never try log(0), which is undefined.
+ * // Multiply by 0.2 to keep it in a usable range.
+ * // min(..., 1) caps the value at 1.
+ * let value = log(1 + t) * 0.2;
+ * value = min(value, 1);
+ *
+ * // Each color is [R, G, B, A] with values from 0 to 1.
+ * let purple = [0.5, 0, 0.5, 1];
+ * let yellow = [1, 1, 0, 1];
+ *
+ * finalColor.begin();
+ *
+ * // mix() blends between purple (when value = 0) and yellow (when value = 1).
+ * // Because log() slows down over time, the color transition decelerates.
+ * finalColor.set(mix(purple, yellow, value));
+ *
+ * finalColor.end();
+ * }
+ *
+ * function draw() {
+ * background(220);
+ * shader(myShader);
+ * noStroke();
+ * sphere(30);
+ * }
+ * ```
+ *
+ * @method log
+ * @param {Number} n number greater than 0.
+ * @return {Number} natural logarithm of n.
*/
fn.log = Math.log;
@@ -498,16 +771,7 @@ function calculation(p5, fn){
* constrains the remapped value to the target range. For example,
* `map(11, 0, 10, 0, 100, true)` returns 100.
*
- * @method map
- * @param {Number} value the value to be remapped.
- * @param {Number} start1 lower bound of the value's current range.
- * @param {Number} stop1 upper bound of the value's current range.
- * @param {Number} start2 lower bound of the value's target range.
- * @param {Number} stop2 upper bound of the value's target range.
- * @param {Boolean} [withinBounds] constrain the value to the newly mapped range.
- * @return {Number} remapped number.
- *
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -526,8 +790,9 @@ function calculation(p5, fn){
* // Draw the bottom line.
* line(0, 75, 0, x);
* }
+ * ```
*
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -546,6 +811,58 @@ function calculation(p5, fn){
* // Draw the circle.
* circle(50, 50, 20);
* }
+ * ```
+ *
+ * `map()` can also be used in shaders with p5.strands. The following example
+ * uses `map()` to remap time values to color in a shader.
+ *
+ * ```js example
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ * myShader = buildColorShader(shaderCallback);
+ * describe('A sphere that shifts between cyan and orange over time.');
+ * }
+ *
+ * function shaderCallback() {
+ * // shaderCallback runs on the GPU. millis() gives ms since start; multiply by 0.001 for seconds.
+ * let t = millis() * 0.001;
+ *
+ * // sin(t) goes between -1 and 1 over time.
+ * let sinVal = sin(t);
+ *
+ * // map() remaps this from the range [-1, 1] to the range [0, 1].
+ * let value = map(sinVal, -1, 1, 0, 1);
+ *
+ * // Each color is [R, G, B, A] with values from 0 to 1.
+ * let cyan = [0, 0.5, 1, 1];
+ * let orange = [1, 0.5, 0, 1];
+ *
+ * finalColor.begin();
+ *
+ * // mix() blends between cyan (when value = 0) and orange (when value = 1).
+ * finalColor.set(mix(cyan, orange, value));
+ *
+ * finalColor.end();
+ * }
+ *
+ * function draw() {
+ * background(220);
+ * shader(myShader);
+ * noStroke();
+ * sphere(30);
+ * }
+ * ```
+ *
+ * @method map
+ * @param {Number} value the value to be remapped.
+ * @param {Number} start1 lower bound of the value's current range.
+ * @param {Number} stop1 upper bound of the value's current range.
+ * @param {Number} start2 lower bound of the value's target range.
+ * @param {Number} stop2 upper bound of the value's target range.
+ * @param {Boolean} [withinBounds] constrain the value to the newly mapped range.
+ * @return {Number} remapped number.
*/
fn.map = function(n, start1, stop1, start2, stop2, withinBounds) {
// p5._validateParameters('map', arguments);
@@ -569,12 +886,7 @@ function calculation(p5, fn){
* The version of `max()` with two or more parameters interprets them as
* individual numbers and returns the largest number.
*
- * @method max
- * @param {Number} n0 first number to compare.
- * @param {Number} n1 second number to compare.
- * @return {Number} maximum number.
- *
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -592,8 +904,9 @@ function calculation(p5, fn){
*
* describe('The number 20 written in the middle of a gray square.');
* }
+ * ```
*
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -614,6 +927,53 @@ function calculation(p5, fn){
*
* describe('The number 20 written in the middle of a gray square.');
* }
+ * ```
+ *
+ * `max()` can also be used in shaders with p5.strands. The following example
+ * uses `max()` to clamp values in a shader.
+ *
+ * ```js example
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ * myShader = buildColorShader(shaderCallback);
+ * describe('A sphere that shifts from rose to steelBlue and stops.');
+ * }
+ *
+ * function shaderCallback() {
+ * // shaderCallback runs on the GPU. millis() gives ms since start; multiply by 0.001 for seconds.
+ * let t = millis() * 0.001;
+ *
+ * // 1 - t * 0.2 decreases steadily over time.
+ * // max(..., 0) ensures the value never goes below 0.
+ * let value = max(1 - t * 0.2, 0);
+ *
+ * // Each color is [R, G, B, A] with values from 0 to 1.
+ * let steelBlue = [0, 0.3, 0.8, 1];
+ * let rose = [1, 0.3, 0.8, 1];
+ *
+ * finalColor.begin();
+ *
+ * // mix() blends between steelBlue (when value = 0) and rose (when value = 1).
+ * // max() clamps the blend so the color stops changing once it reaches steelBlue.
+ * finalColor.set(mix(steelBlue, rose, value));
+ *
+ * finalColor.end();
+ * }
+ *
+ * function draw() {
+ * background(220);
+ * shader(myShader);
+ * noStroke();
+ * sphere(30);
+ * }
+ * ```
+ *
+ * @method max
+ * @param {Number} n0 first number to compare.
+ * @param {Number} n1 second number to compare.
+ * @return {Number} maximum number.
*/
/**
* @method max
@@ -645,12 +1005,7 @@ function calculation(p5, fn){
* The version of `min()` with two or more parameters interprets them as
* individual numbers and returns the smallest number.
*
- * @method min
- * @param {Number} n0 first number to compare.
- * @param {Number} n1 second number to compare.
- * @return {Number} minimum number.
- *
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -668,8 +1023,9 @@ function calculation(p5, fn){
*
* describe('The number 5 written in the middle of a gray square.');
* }
+ * ```
*
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -690,6 +1046,53 @@ function calculation(p5, fn){
*
* describe('The number 5 written in the middle of a gray square.');
* }
+ * ```
+ *
+ * `min()` can also be used in shaders with p5.strands. The following example
+ * uses `min()` to clamp values in a shader.
+ *
+ * ```js example
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ * myShader = buildColorShader(shaderCallback);
+ * describe('A sphere that shifts from red to green and stops.');
+ * }
+ *
+ * function shaderCallback() {
+ * // shaderCallback runs on the GPU. millis() gives ms since start; multiply by 0.001 for seconds.
+ * let t = millis() * 0.001;
+ *
+ * // t * 0.2 grows steadily over time.
+ * // min(..., 1) caps the value at 1 so it doesn't go past the target color.
+ * let value = min(t * 0.2, 1);
+ *
+ * // Each color is [R, G, B, A] with values from 0 to 1.
+ * let deepRed = [0.8, 0, 0.2, 1];
+ * let yellowGreen = [0.8, 1, 0.2, 1];
+ *
+ * finalColor.begin();
+ *
+ * // mix() blends between deepRed (when value = 0) and yellowGreen (when value = 1).
+ * // min() clamps the blend so the color stops changing once it reaches yellowGreen.
+ * finalColor.set(mix(deepRed, yellowGreen, value));
+ *
+ * finalColor.end();
+ * }
+ *
+ * function draw() {
+ * background(220);
+ * shader(myShader);
+ * noStroke();
+ * sphere(30);
+ * }
+ * ```
+ *
+ * @method min
+ * @param {Number} n0 first number to compare.
+ * @param {Number} n1 second number to compare.
+ * @return {Number} minimum number.
*/
/**
* @method min
@@ -758,12 +1161,7 @@ function calculation(p5, fn){
* 2 × 2 × 2. `pow(2, -3)` evaluates 1 ÷
* (2 × 2 × 2).
*
- * @method pow
- * @param {Number} n base of the exponential expression.
- * @param {Number} e power by which to raise the base.
- * @return {Number} n^e.
- *
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -790,6 +1188,54 @@ function calculation(p5, fn){
*
* describe('A series of circles that grow exponentially from top left to bottom right.');
* }
+ * ```
+ *
+ * `pow()` can also be used in shaders with p5.strands. The following example
+ * uses `pow()` to create a gamma curve effect on colors in a shader.
+ *
+ * ```js example
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ * myShader = buildColorShader(shaderCallback);
+ * describe('A sphere with colors that shift with a power curve.');
+ * }
+ *
+ * function shaderCallback() {
+ * // shaderCallback runs on the GPU. millis() gives ms since start; multiply by 0.0005 to slow it.
+ * let t = millis() * 0.0005;
+ *
+ * // pow(t, 2) squares the time value: it starts slow then accelerates.
+ * // Multiply by 0.001 so it doesn't reach 1 too quickly.
+ * // min(..., 1) caps the value at 1.
+ * let value = min(pow(t, 2) * 0.001, 1);
+ *
+ * // Each color is [R, G, B, A] with values from 0 to 1.
+ * let deepBlue = [0, 0.1, 0.5, 1];
+ * let gold = [1, 0.8, 0, 1];
+ *
+ * finalColor.begin();
+ *
+ * // mix() blends between deepBlue (when value = 0) and gold (when value = 1).
+ * // Because pow() accelerates, the color transition gets faster over time.
+ * finalColor.set(mix(deepBlue, gold, value));
+ *
+ * finalColor.end();
+ * }
+ *
+ * function draw() {
+ * background(220);
+ * shader(myShader);
+ * noStroke();
+ * sphere(30);
+ * }
+ * ```
+ *
+ * @method pow
+ * @param {Number} n base of the exponential expression.
+ * @param {Number} e power by which to raise the base.
+ * @return {Number} n^e.
*/
fn.pow = Math.pow;
@@ -802,12 +1248,7 @@ function calculation(p5, fn){
* decimal places to use when rounding. For example, `round(12.34, 1)` returns
* 12.3. `decimals` is 0 by default.
*
- * @method round
- * @param {Number} n number to round.
- * @param {Number} [decimals] number of decimal places to round to, default is 0.
- * @return {Integer} rounded number.
- *
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -825,8 +1266,9 @@ function calculation(p5, fn){
*
* describe('The number 4 written in middle of the canvas.');
* }
+ * ```
*
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -844,6 +1286,57 @@ function calculation(p5, fn){
*
* describe('The number 12.78 written in middle of canvas.');
* }
+ * ```
+ *
+ * `round()` can also be used in shaders with p5.strands. The following example
+ * uses `round()` to quantize colors in a shader.
+ *
+ * ```js example
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ * myShader = buildColorShader(shaderCallback);
+ * describe('A sphere with posterized quantized colors.');
+ * }
+ *
+ * function shaderCallback() {
+ * // shaderCallback runs on the GPU. millis() gives ms since start; multiply by 0.001 for seconds.
+ * let t = millis() * 0.001;
+ *
+ * // sin(t) goes between -1 and 1.
+ * // 0.5 + 0.5 * sin(t) remaps this to the 0 to 1 range.
+ * let sinVal = 0.5 + 0.5 * sin(t);
+ *
+ * // Multiply by 4 then round to get 5 distinct levels (0, 0.25, 0.5, 0.75, 1).
+ * // Divide by 4 to bring the result back to the 0 to 1 range.
+ * let value = round(sinVal * 4) / 4;
+ *
+ * // Each color is [R, G, B, A] with values from 0 to 1.
+ * let mutedBlue = [0.3, 0.4, 0.7, 1];
+ * let rose = [0.8, 0.3, 0.4, 1];
+ *
+ * finalColor.begin();
+ *
+ * // mix() blends between mutedBlue (when value = 0) and rose (when value = 1).
+ * // The round() creates stepped bands of color like a posterization effect.
+ * finalColor.set(mix(mutedBlue, rose, value));
+ *
+ * finalColor.end();
+ * }
+ *
+ * function draw() {
+ * background(220);
+ * shader(myShader);
+ * noStroke();
+ * sphere(30);
+ * }
+ * ```
+ *
+ * @method round
+ * @param {Number} n number to round.
+ * @param {Number} [decimals] number of decimal places to round to, default is 0.
+ * @return {Integer} rounded number.
*/
fn.round = function(n, decimals) {
if (!decimals) {
@@ -914,11 +1407,7 @@ function calculation(p5, fn){
* always returns a positive value. `sqrt()` doesn't work with negative arguments
* such as `sqrt(-9)`.
*
- * @method sqrt
- * @param {Number} n non-negative number to square root.
- * @return {Number} square root of number.
- *
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -934,8 +1423,9 @@ function calculation(p5, fn){
*
* describe('Two white circles. The circle at the top-left is small. The circle at the bottom-right is ten times larger.');
* }
+ * ```
*
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -956,6 +1446,63 @@ function calculation(p5, fn){
* // Draw the point.
* point(x, y);
* }
+ * ```
+ *
+ * `sqrt()` can also be used in shaders with p5.strands. The following example
+ * uses `sqrt()` to create a smooth ease-out curve on color and size.
+ *
+ * ```js example
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ * myShader = buildColorShader(shaderCallback);
+ * describe('A sphere that grows and shifts from navy to orange with an ease-out curve.');
+ * }
+ *
+ * function shaderCallback() {
+ * // shaderCallback runs on the GPU. millis() gives ms since start; multiply by 0.001 for seconds.
+ * let t = millis() * 0.001;
+ *
+ * // sin(t) goes between -1 and 1.
+ * // 0.5 + 0.5 * sin(t) remaps this to the 0 to 1 range.
+ * let sinVal = 0.5 + 0.5 * sin(t);
+ *
+ * // sqrt(sinVal) creates an ease-out curve: fast start, slow finish.
+ * // Since sinVal is in [0,1], sqrt() stays in [0,1].
+ * let value = sqrt(sinVal);
+ *
+ * // Each color is [R, G, B, A] with values from 0 to 1.
+ * let navy = [0, 0.1, 0.4, 1];
+ * let brightOrange = [1, 0.6, 0, 1];
+ *
+ * finalColor.begin();
+ *
+ * // mix() blends between navy (when value = 0) and brightOrange (when value = 1).
+ * // The sqrt() ease-out makes the color change fast at first, then slow down.
+ * finalColor.set(mix(navy, brightOrange, value));
+ *
+ * finalColor.end();
+ * }
+ *
+ * function drawShape() {
+ * let t = millis() * 0.001;
+ * let sinVal = 0.5 + 0.5 * sin(t);
+ * let size = 10 + sqrt(sinVal) * 30;
+ * sphere(size);
+ * }
+ *
+ * function draw() {
+ * background(220);
+ * shader(myShader);
+ * noStroke();
+ * drawShape();
+ * }
+ * ```
+ *
+ * @method sqrt
+ * @param {Number} n non-negative number to square root.
+ * @return {Number} square root of number.
*/
fn.sqrt = Math.sqrt;
@@ -965,11 +1512,7 @@ function calculation(p5, fn){
* A number's fractional part includes its decimal values. For example,
* `fract(12.34)` returns 0.34.
*
- * @method fract
- * @param {Number} n number whose fractional part will be found.
- * @returns {Number} fractional part of n.
- *
- * @example
+ * ```js example
* function setup() {
* createCanvas(100, 100);
*
@@ -989,6 +1532,53 @@ function calculation(p5, fn){
*
* describe('The number 56.78 written above the number 0.78.');
* }
+ * ```
+ *
+ * `fract()` can also be used in shaders with p5.strands. The following example
+ * uses `fract()` to create repeating patterns in a shader.
+ *
+ * ```js example
+ * let myShader;
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ * myShader = buildColorShader(shaderCallback);
+ * describe('A sphere with a repeating gradient pattern.');
+ * }
+ *
+ * function shaderCallback() {
+ * // shaderCallback runs on the GPU. millis() gives ms since start; multiply by 0.001 for seconds.
+ * let t = millis() * 0.001;
+ *
+ * // Multiply by 0.5 to slow the animation to half speed.
+ * // fract(t * 0.5) extracts only the decimal part of the number.
+ * // This creates a smooth sawtooth wave that repeats every 2 seconds.
+ * let value = fract(t * 0.5);
+ *
+ * // Each color is [R, G, B, A] with values from 0 to 1.
+ * let cyan = [0, 0.5, 1, 1];
+ * let orange = [1, 0.5, 0, 1];
+ *
+ * finalColor.begin();
+ *
+ * // mix() blends between cyan (when value = 0) and orange (when value = 1).
+ * // Because fract() resets to 0 each cycle, the color loops smoothly.
+ * finalColor.set(mix(cyan, orange, value));
+ *
+ * finalColor.end();
+ * }
+ *
+ * function draw() {
+ * background(220);
+ * shader(myShader);
+ * noStroke();
+ * sphere(30);
+ * }
+ * ```
+ *
+ * @method fract
+ * @param {Number} n number whose fractional part will be found.
+ * @returns {Number} fractional part of n.
*/
fn.fract = function(toConvert) {
// p5._validateParameters('fract', arguments);