I started using p5.js in December, 2019. I wanted to have two canvases for my first significant application and was really disappointed to read "Calling createCanvas more than once in a sketch will result in very unpredictable behavior." Because that has not a HTML or Javascript restriction, I decided to see if there was away around this problem. My first effort was semi-successful but required a lot of coding. Then I learned about instance mode which supposedly solves the problem but in my experience seems to be mystical and makes it difficult to use events.
I started over again and came up with CanvasClass (for the lack of a better name). As the name suggests, it declares a CanvasClass class. I think it enables users to avoid the problems with instance mode. Most of the p5.js methods (except for some WEBGL methods when used "in motion") and events for the canvas work. Over 110 functions are believed to work with over a dozen additional ones that work in part.
Here is a very simple example that uses two canvases and demonstrates the type of coding needed. Notice that one has to name each canvas and use the name whenever referring to the canvas or the mouse. Drag your mouse over the two canvases and click on the first one. You will notice that the events and mouse values only work when the mouse is over the canvas.
let canvas1, canvas2, backgroundColor1; function setup() { canvas1 = createCanvasClass(180, 170); canvas1.parent("Example"); canvas1.fill(255, 0, 0); canvas1.mouseClicked(clicked); backgroundColor1 = "FloralWhite"; canvas2 = createCanvasClass(150, 200); canvas2.parent("Example"); canvas2.stroke(255, 0, 255); } function draw() { canvas1.background(backgroundColor1); canvas1.rect(canvas1.mouseX, canvas1.mouseY, 100 ,80); canvas2.background("Khaki"); canvas2.line(canvas2.mouseX, canvas2.mouseY, 75, 100); } function clicked() { if (backgroundColor1 == "FloralWhite") { backgroundColor1 = "LightCyan"; } else { backgroundColor1 = "FloralWhite"; } } |
Notice that names for canvases and mouse positions are used consistently. In regular p5 canvases there are times when a canvas name is required and other times when it is not allowed.
Want to be able to follow the mouse even when the mouse is not over the canvas? See philExample.html.
A significant problem is related to the fact that p5.js resets some transformations (using resetMatrix) and WEBGL rotations every time a new frame is drawn. Unfortunately I haven't figured out how to do either automatically. It is relatively easy to solve problems related to resetMatrix, translate, rotate, and scale but I have been unable to solve problems related to WEBGL. 16 methods WEBGL methods have been implemented: (plane, box, cylinder, cone, torus, sphere, ambientLight, pointLight, specularColor, normalMaterial, ambientMaterial, specularMaterial, shininess, rotateX, rotateY, and rotateZ). All of these methods work when used in setup(). Implementing them was easy. But there is a problem. The first 9 work nicely when used in draw() unless the object is put in motion using 3 rotate methods. I am pretty sure that the problem is related to the fact the rotations are not reset every time a new frame is drawn.
I am sure that persons who better understand instance mode, nameSpace, _pInst and renderer could write better code and solve the problems with resetting things with each time draw() is executed. There were some times I had to make choices about how to implement methods - some of those choices are debatable. Unfortunately, there are probably still some coding errors despite a lot of testing.
CanvasClass actually uses instance mode to create the canvas but hides it so users don't need to be concerned with it. Most methods are trivial to implement but a few (particularly those that use hidden data) had to be rewritten.
implementation.html Lists the methods and other elements that have been implemented CanvasClass.
Some examples and testing:
sketch.html A program to allow drawing with
different shapes that uses several CanvasClass methods.
ball.html A rewrite of a
SonnySanberg demo with three bouncing ball using CanvasClass.
Birthday.html A fun page that uses one
CanvasClass.
bezier.html Demo using bezier curves.
Enlarge.html Allows one to load a large image
file into one CanvasClass and then look at a enlarged portion of it in a
second CanvasClass.
child.html Tests child, text, style, id, background,
elt, canvas, and fill comparing them to a regular p5.js canvas.
colors.html Tests several color related methods.
colorTest.html Test several color related
methods with emphasis on colorMode, HSL and HSB.
CanvasClassTest.html Test over 50
methods using 15 canvases.
image.html Tests image, blend, background(image)
and pixelDensity
domImage.html Tests parent, id, clear,
text, background, rect, applyMatrix, resetMatrix, image, and imageMode.
rotation.pjs Demonstrates successes and failures
when working with WEBGL and "in-motion" rotations.
webgl.html Also demonstrates successes and failures
when working with WEBGL and "in-motion" rotations. Tests the several WEBGL
related methods that have been implemented.
ambient.html Tests several material and light
WEBGL functions.
testRotation.html Illustrates some rotations
and translations that work.
events.html Tests many events.
events2.html Illustrates how to use CanvasClass
events.
hideShow.html Tests resize, hide and show
demonstrating the CanvasClass option to show the canvas inline.
save.html Tests saveCanvas.
TV.html There are 4 "TV's" each doing there own
thing. It tests image, mouseClicked and keyIsPressed along with several
methods.
transforms.html Tests resetMatrix, scale,
rotate, and translate along with several other methods.
get.html Tests get. Works correctly with
2 arguements but not with 0 or 4.
getImageFromWebPage.html
Tests and demonstates 3 ways to load images from the web page. Loading
images from the web pages avoids having to preload or use local servers.
Any help in solving these problems would be appreciated.
If you have an application you would like to share, have questions, suggestions, or comments, please let me know. brinkje@plu.edu
The CanvasClass.pjs file.
CanvasClass.zip a zip file containing all the files listed above.
James Brink, 8/29/2020