v2.0.0-beta.2
Pre-releaseThe library is available from JSDelivr:
- p5.js - https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js
- p5.min.js - https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.min.js
You can duplicate this p5.js web editor project: https://editor.p5js.org/davepagurek/sketches/RwD_DbVR7
You can also import p5
directly from NPM as an ESM module. More documentation on ESM usage to come.
What's Changed
- Merged main into 2.0
- Fix bug where
pixels
is not available - Fixed
model()
not working insidebuildGeometry()
- Fixed WebGL text alignment bugs
- Fixed bugs in closed splines
What to test
Async loading (thanks to @limzykenneth)
Rather than having a preload
function, p5 2.0 has async setup
!
1.x | 2.0 |
---|---|
let img;
function preload() {
img = loadImage('cat.jpg');
}
function setup() {
createCanvas(200, 200);
} |
let img;
async function setup() {
createCanvas(200, 200);
img = await loadImage('cat.jpg');
} |
🚧 Since this is a breaking change from 1.x to 2.0, you can weight in on the compatibility discussion here
Support for loading fonts via CSS (thanks to @dhowe)
In 2D mode, try loading fonts via a a path to a CSS font file, such as a Google Fonts link!
loadFont("https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,[email protected],200..800&display=swap")
loadFont(`@font-face { font-family: "Bricolage Grotesque", serif; font-optical-sizing: auto; font-weight: <weight> font-style: normal; font-variation-settings: "wdth" 100; }`);
loadFont({
fontFamily: '"Bricolage Grotesque", serif',
fontOpticalSizing: 'auto',
fontWeight: '<weight>',
fontStyle: 'normal',
fontVariationSettings: '"wdth" 100',
});
loadFont("https://fonts.gstatic.com/s/inter/v18/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuLyfMZhrib2Bg-4.ttf");
loadFont("path/to/localFont.ttf");
loadFont("system-font-name");
Support for variable font weight (thanks to contributions by @dhowe)
In 2D mode, if you've loaded a variable font, try changing its weight!
var font;
async function setup() {
createCanvas(100, 100);
font = await loadFont(
'https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900;1,100..900&display=swap'
);
}
function draw() {
background(255);
textFont(font);
textAlign(LEFT, TOP);
textSize(35);
textWeight(sin(millis() * 0.002) * 200 + 400);
text('p5*js', 0, 10);
}
More ways to draw and manipulate text (thanks to @davepagurek)
Like how textToPoints()
gives you points on text, the new textToContours()
function lets you edit the points on text and then draw them with fills!
createCanvas(100, 100);
const font = await loadFont('myFont.ttf');
background(200);
strokeWeight(2);
textSize(50);
const contours = font.textToContours('p5*js', 0, 50, { sampleFactor: 0.5 });
beginShape();
for (const pts of contours) {
beginContour();
for (const pt of pts) {
vertex(pt.x + 20*sin(pt.y*0.01), pt.y + 20*sin(pt.x*0.01));
}
endContour(CLOSE);
}
endShape();
In WebGL, you can use textToModel
to extrude a 3D model out of your text:
createCanvas(100, 100, WEBGL);
const font = await loadFont('myFont.ttf');
background(200);
textSize(50);
const geom = font.textToModel('p5*js', 0, 50, { sampleFactor: 2, extrude: 20 });
orbitControl();
model(geom);
A new pointer event handling system (thanks to @diyaayay)
Instead of having separate methods for mouse and touch, we now use the browser's pointer API to handle both simultaneously. Try defining mouse functions as usual and accessing the global touches
array to see what pointers are active for multitouch support!
Custom shader attributes (thanks to @lukeplowden)
If you are using a shader and want custom per-vertex properties in addition to uniform
s, which are the same across the whole shape, you can now call vertexProperty(name, value)
before vertices.
const vertSrc = `#version 300 es
precision mediump float;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
in vec3 aPosition;
in vec2 aOffset;
void main(){
vec4 positionVec4 = vec4(aPosition.xyz, 1.0);
positionVec4.xy += aOffset;
gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
}
`;
const fragSrc = `#version 300 es
precision mediump float;
out vec4 outColor;
void main(){
outColor = vec4(0.0, 1.0, 1.0, 1.0);
}
`;
function setup(){
createCanvas(100, 100, WEBGL);
// Create and use the custom shader.
const myShader = createShader(vertSrc, fragSrc);
shader(myShader);
describe('A wobbly, cyan circle on a gray background.');
}
function draw(){
// Set the styles
background(125);
noStroke();
// Draw the circle.
beginShape();
for (let i = 0; i < 30; i++){
const x = 40 * cos(i/30 * TWO_PI);
const y = 40 * sin(i/30 * TWO_PI);
// Apply some noise to the coordinates.
const xOff = 10 * noise(x + millis()/1000) - 5;
const yOff = 10 * noise(y + millis()/1000) - 5;
// Apply these noise values to the following vertex.
vertexProperty('aOffset', [xOff, yOff]);
vertex(x, y);
}
endShape(CLOSE);
}
Updated bezier and curve drawing functions (thanks to @GregStanton)
First off: you can combine multiple types of curves in one begin/endShape()
block now!
Long cubic and quadratic bezier vertex calls are now split up into their individual control points. Both cubic and quadratic curves are done with bezierVertex
now, and you can set bezierOrder()
to change from cubic (order 3) to quadratic (order 2). For WebGL mode, this also means you can also specify texture coordinates per control point, or change the fill, stroke, normal, and more between control points.
1.x | 2.0 |
---|---|
beginShape();
vertex(10, 10);
vertex(30, 10);
bezierVertex(35, 10, 40, 15, 40, 20);
vertex(40, 30);
quadraticVertex(40, 40, 30, 40);
vertex(10, 40);
endShape(CLOSE); |
beginShape();
vertex(10, 10);
vertex(30, 10);
// Default cubic
bezierVertex(35, 10);
bezierVertex(40, 15);
bezierVertex(40, 20);
vertex(40, 30);
bezierOrder(2);
bezierVertex(40, 40);
bezierVertex(30, 40);
vertex(10, 40);
endShape(p5.CLOSE); |
We've renamed curveVertex
to splineVertex
and have given it more options. By default, it will now go through every splineVertex
, so you no longer have to double up the first/last point to get it to go through it:
1.x | 2.0 |
---|---|
beginShape();
curveVertex(10, 10);
curveVertex(10, 10);
curveVertex(15, 40);
curveVertex(40, 35);
curveVertex(25, 15);
curveVertex(15, 25);
curveVertex(15, 25);
endShape(); |
beginShape();
splineVertex(10, 10);
splineVertex(15, 40);
splineVertex(40, 35);
splineVertex(25, 15);
splineVertex(15, 25);
endShape(); |
Similarly, endShape(CLOSE)
(or endContour(CLOSE)
if you're in a contour) will cause a spline to smoothly loop back on itself so you no longer need to double up any points:
1.x | 2.0 |
---|---|
beginShape();
curveVertex(15, 25);
curveVertex(10, 10);
curveVertex(15, 40);
curveVertex(40, 35);
curveVertex(25, 15);
curveVertex(15, 25);
curveVertex(10, 10);
curveVertex(15, 40);
endShape(); |
beginShape();
splineVertex(10, 10);
splineVertex(15, 40);
splineVertex(40, 35);
splineVertex(25, 15);
splineVertex(15, 25);
endShape(CLOSE); |
🚧 Since this is a breaking change from 1.x to 2.0, you can weight in on the compatibility discussion here
A new simple lines mode for WebGL (thanks to contributions from @perminder-17)
If you are drawing lots of shapes, and don't need stroke caps or joins, you can use a simple lines mode for increased performance in WebGL. You can activate this mode by calling linesMode(SIMPLE)
in your sketch.
Custom shaders for fills, strokes, images (thanks to @Garima3110 and @perminder-17)
You can now create your own shaders for fills, strokes, and images, and have them all applied at once! Use shader()
to set a fill shader, strokeShader()
to set a stroke shader, and imageShader()
to set an image shader. Try using baseMaterialShader().modify(...)
and baseStrokeShader().modify(...)
to create custom shaders.
let myFillShader = baseMaterialShader.modify({
'vec4 getFinalColor': `(vec4 color) {
return vec4(1., 1., 0., 1.);
}`
});
let myStrokeShader = baseStrokeShader.modify({
'vec4 getFinalColor': `(vec4 color) {
return vec4(1., 0., 1., 1.);
}`
});
let myImageShader = baseMaterialShader.modify({
'vec4 getFinalColor': `(vec4 color) {
return vec4(0., 1., 1., 1.);
}`
});
shader(myFillShader);
strokeShader(myStrokeShader);
imageShader(myImageShader);
sphere(); // Draws with the custom stroke and image shaders
image(myImg, 0, 0); // Draws with the custom image shader
A new public p5.Matrix
class (thanks to @holomorfo)
TODO add examples
Support for more color spaces in p5.Color
(thanks to @limzykenneth and @dianamgalindo)
p5.js 2.0 now supports more color modes in addition to the existing RGB, HSB, and HSL color modes. Here are the list of new supported color mode and brief description of them:
RGBHDR
- High Dynamic Range RGB color defined within the Display P3 color space. You will need to use the HDR canvas described below to draw this color on the canvas accurately.HWB
- Hue, Whiteness, Blackness. This is similar toHSL
andHSB
in that you will define a hue angle however instead of saturation and lightness, you will define the percentage of whiteness and blackness. It is the color model of the GUI color picker used by Chrome.
LAB
- Also called CIE Lab, defines color with Lightness, Alpha, and Beta. The color space is often used in professional color measuring context.LCH
- An easier to use representation of a CIE Lab color with definition of Lightness, Chroma, and Hue instead.OKLAB
- OkLab is a slight adjustment to CIE Lab color space mainly to fix a non-uniformity issue that exist in CIE Lab. This difference is more visible in the example below.OKLCH
- An easier to use representation of an OkLab color with definition of Lightness, Chroma, and Hue instead.
Comparing HSL
, LCH
, and OKLCH
in a sketch below:
From left to right are color wheels of HSL
, LCH
, and OKLCH
respectively. Notice the evenness of color distribution between each wheel with OkLCH having the most even distribution. It can be noted that the LCH wheel has a large blue section that is fixed by OkLCH.
To use these new color spaces in p5.js 2.0, the respective constants have been added and the colorMode()
function can be used with these constants in the same way as RGB
, HSL
, and HSB
.
function setup(){
createCanvas(200, 200);
}
function draw(){
colorMode(OKLCH);
background(220); // Should show a teal colored canvas
}
Support for wide-gamut colors with the display-p3
mode (thanks to @limzykenneth)
You can now create a 2D canvas that supports HDR colors that will give you a more vibrant sketch and also HDR images. To use a HDR canvas you will need to create it using the P2DHDR
constant like below:
function setup(){
createCanvas(400, 400, P2DHDR);
}
When a P2DHDR
canvas is created, the default color mode will be switched to the new RGBHDR
color mode instead of RGB
. In practice you can continue to use the same RGB color definition you have always used.
function setup(){
createCanvas(400, 400, P2DHDR);
}
function draw(){
background(255, 0, 0);
fill(100, 255, 0);
circle(100, 100, 50);
}
This example sketch shows a direct comparison between HDR and non-HDR colors, you should see three bands of red, green, and blue colors with a slightly dimmer red, green, and blue circles within. However, both your browser and your screen will need to support HDR to see the difference. Currently Firefox on desktop does not support HDR canvas so if you do not see a difference, try a different browser such as Safari or Chrome.
You can also now load HDR images and have them be displayed in full HDR in a HDR canvas. If you see a dark image on the linked sketch, your browser or screen does not support HDR and you should try a different browser/device.
What's Changed 🎊
- Fix panorama() by @davepagurek in #7154
- Fix unnecessary console warnings when using smooth() on P2D Graphics objects by @zeesworth in #7159
- added paletteLerp by @RandomGamingDev in #6960
- imageLight - panorama shader bug, added @perminder-17 code snippet by @PimTournaye in #7169
- Tie FES initialization to only run just before p5 init by @limzykenneth in #7173
- Code block updates in
vertex.js
by @DenisovichDev in #7174 - Fix incorrect pixel offset in updatePixels() by @Forchapeatl in #7177
- fix for #7181 by @orrkislev in #7182
- Fix Camera.eyeX comment by @Psychpsyo in #7184
- Solves issue #6891 by @Garima3110 in #7165
- Fix: Added unique group names for radio buttions by @Forchapeatl in #7162
- add non-code contributions to contrib guidelines readme by @sarahciston in #6941
- Caps at the beginning of the curve by @diyaayay in #7201
- Added useLinePerspective to cam copy properties by @TiborUdvari in #7213
- Update README.md to include an updated get started link by @willallstet in #7232
- Fix : broken link in contributor_docs/webgl_mode_architecture.md by @ashwanidey in #7235
- Fix broken links in contributor_docs/steward_guidelines.md by @aleannab in #7240
- Fix broken link in contributing_to_the_p5js_references.md by @aleannab in #7242
- Fix : broken link in contributor_docs/webgl_contribution_guide.md by @ashwanidey in #7239
- Fix Broken README Link by @benpalevsky in #7216
- Fix clipping bug with ellipses by @jeanetteandrews in #7249
- Fixed the broken link on p5.js website page for "p5.js Web Accessibility" by @shourysingh07 in #7254
- Fixed the broken link on p5.js website page for "Our Focus on Access" by @shourysingh07 in #7255
- Fixed broken links for p5js references by @visheshrwl in #7253
- fix: added
WEBGL
mode for correct blendMode(SUBTRACT) behavior by @Abhinavcode13 in #7229 - fix: broken links in lerpColor() by @M0nica in #7241
- Refactor arc and rect to use canvas methods rather than curves by @ksen0 in #7205
- Fix broken links in contributor_docs/access.md by @aleannab in #7243
- Fixed the broken link on p5.js website page for "WebGL Contribution Guide". by @shourysingh07 in #7263
- Fixed the broken link on p5.js website page for "How to add Friendly Error Messages" by @shourysingh07 in #7264
- Shader hooks by @davepagurek in #7149
- Add list support for
lerpColor
like other color functions by @RandomGamingDev in #6954 - Remove 2.0 built file by @davepagurek in #7274
- Added textAscent and textDescent functions on Webgl by @Forchapeatl in #7187
- Line.vert fix for small units by @TiborUdvari in #7206
- fixed textpoint alignment by @mathewpan2 in #6967
- Fixed minor error in documentation for p5.Vector.sub() by @jaredberghold in #7265
- Rename default shader methods to have a base* prefix by @davepagurek in #7288
- Performance improvements for WebGL shape drawing by @davepagurek in #7287
- Change Reference Example by @samarsrivastav in #7280
- Fix example of createModel function. by @shibomb in #7298
- fix missing example tag in documentation for color's toString method by @ashish1729 in #7302
- fixed nf to work with negative number by @Akhilbisht798 in #7054
- textureData updated to fix flipping property for webgl by @MuktiMishra in #7305
- Fixes language reference and Markdown syntax by @danicruz0415 in #7314
- fix typo by @asukaminato0721 in #7322
- Fix ellipseMode(CORNERS) and rectMode(CORNER) by @martinleopold in #7290
- add usage of dist by @asukaminato0721 in #7324
- Fix broken links in contributor-doc by @shibomb in #7320
- Fix broken links in website references by @shibomb in #7321
- Uses canvas dimensions instead of arbitrary constants for
noise()
andnoiseDetail()
by @RandomGamingDev in #7330 - mouseY reference first example issue fixed by @shourysingh07 in #7311
- Docs: "A maximum of 5 directional lights can be active at once." by @blackboxlogic in #7337
- Switch all-contributor shield styling to match other shields by @SableRaf in #7347
- Fix a typo (dpeth -> depth) in webgl/p5.Framebuffer.js by @zs-5 in #7348
- Save/restore textureMode with push/pop by @davepagurek in #7358
- fix: Correct typo, improve createRadio() method description, and simplify input tag by @Dhanush111 in #7315
- Update links to point to tutorial page by @muffinista in #7318
- fix add alpha doc by @asukaminato0721 in #7362
- Negative dimensions will mirror rect() again by @martinleopold in #7363
- fixes issue #7366: Adjust Option Orientation in CreateRadio() reference. by @Prajyot05 in #7367
- Added ability to use setUniform for textures by texture slot rather than by p5.Texture by @RandomGamingDev in #7395
- The text properly displayed on Mobile. by @mahi6299 in #7399
- Updated README by @ksen0 in #7408
- Update p5.Geometry.js by fixed cap color problem by @mahaidong in #7413
- Added support for other WebGL sampler types by @RandomGamingDev in #7411
- fixed repeated key presses when a modifier key is held by @Rishab87 in #7435
- Fix typo in image.js docs by @reidab in #7462
- Add and adjust alpha parameter description by @FrauBoes in #7420
- Documentation Update:Webgl - .lib files not supported by @atmajaa in #7454
- Add 0 check before dividing color by alpha by @davepagurek in #7478
- Fix usage of model() in buildGeometry() by @davepagurek in #7479
- Fix WebGL text alignment + add tests by @davepagurek in #7481
- Implement splineProperty by @davepagurek in #7471
- Documentation Foundation Class: remove dupe example and describe color by @philyawj in #7483
- Fixed typo in p5.Shader.js documentation comment by @ImRAJAS-SAMSE in #7458
- Update sketch verifier to check for redefinitions and print friendly messages by @sproutleaf in #7326
- Add angle param clarification to sin(), cos(), and tan() by @thrly in #7475
- fixed some broken links in markdown files by @lirenjie95 in #7485
- Fix buildGeometry absorbing the ambient fill color by @davepagurek in #7489
- Fix closed curves having extra loops by @davepagurek in #7495
- Fix FES errors, parameter data omitting classes by @davepagurek in #7497
- Merge main into dev-2.0 by @davepagurek in #7509
New Contributors
- @zeesworth made their first contribution in #7159
- @PimTournaye made their first contribution in #7169
- @DenisovichDev made their first contribution in #7174
- @Forchapeatl made their first contribution in #7177
- @orrkislev made their first contribution in #7182
- @Psychpsyo made their first contribution in #7184
- @sarahciston made their first contribution in #6941
- @TiborUdvari made their first contribution in #7213
- @willallstet made their first contribution in #7232
- @ashwanidey made their first contribution in #7235
- @aleannab made their first contribution in #7240
- @benpalevsky made their first contribution in #7216
- @jeanetteandrews made their first contribution in #7249
- @shourysingh07 made their first contribution in #7254
- @visheshrwl made their first contribution in #7253
- @M0nica made their first contribution in #7241
- @mathewpan2 made their first contribution in #6967
- @jaredberghold made their first contribution in #7265
- @samarsrivastav made their first contribution in #7280
- @Akhilbisht798 made their first contribution in #7054
- @MuktiMishra made their first contribution in #7305
- @danicruz0415 made their first contribution in #7314
- @martinleopold made their first contribution in #7290
- @blackboxlogic made their first contribution in #7337
- @zs-5 made their first contribution in #7348
- @Dhanush111 made their first contribution in #7315
- @muffinista made their first contribution in #7318
- @Prajyot05 made their first contribution in #7367
- @mahi6299 made their first contribution in #7399
- @mahaidong made their first contribution in #7413
- @reidab made their first contribution in #7462
- @FrauBoes made their first contribution in #7420
- @atmajaa made their first contribution in #7454
- @philyawj made their first contribution in #7483
- @ImRAJAS-SAMSE made their first contribution in #7458
- @thrly made their first contribution in #7475
- @lirenjie95 made their first contribution in #7485
Full Changelog: v2.0.0-beta.1...v2.0.0-beta.2