I released G4P for Javamode just over 13 years ago but now I am getting into Javascript I intend to create a GUI library for p5.js The idea behind the library is to give p5.js users a similar experience for those like me who started with Java mode.
I aim to create a library that
behaves the same in both P2D and WEBGL without having to make sketch code changes
is easy to learn and use
provide sophisticated flexible / features but with a simple API
So if you follow the link below you can see the library (so far) in action. I have taken one of the 3D examples that come with Processing and added a simple GUI. Just labels, buttons and sliders but more controls to follow.
Since I am starting this from scratch I will be interested in any feedback that might improve the final library. The next stage is to expand the available controls to include checkboxes and radio buttons but I am interested in what other controls users might like to see.
Just had a look at q5xjs and it is supposed to mirror the p5.js API . If that is correct then q4js should work without changes.
Pjs has been archived because p5.js effectively replaced it, so I have no interest in compatibility there.
I assume you mean “will g4js have the same API as G4P?”. No as I want to take advantage of JS to streamline the code to create the GUI. For instance in the above sketch this is the code to create the red slider.
where r is a global variable used to hold the red channel value for the ball colour. This is much terser and easier to follow than the equivalent G4P code.
Rather than rush to reply I have taken the time to do a little more research and to think seriously about your comments re compatibility.
Pjs is no longer under active development so users like Khan academy are creating their own modified versions to suit their needs. Trying to keep q4js compatible with possibly multiple versions of Pjs is just not realistic and certainly not worth the effort. If they want to include q4js they can create a modified version that works with their modified version of Pjs My final thought is without active development the user base for Pjs will become insignificant ior even nonexistent.
The developers of q5.js describe it as ‘experimental’ and incomplete so keeping q5.js compatible with it is like shooting a moving target and involves a lot of work. Once q5.js has reached the same development stage as p5.js then I will reconsider making g4js compatible.
That is very true but -
even without G4P converting a non-trivial Java Mode sketch to work in p5.js is not easy (I know I have done it)
only a small minority of users will want to port sketches that use G4P
anyone capable of creating a gui with G4P should have no trouble creating the equivalent in q4js as the syntax will be much simpler.
I want the freedom to create a new API that is easier to learn and use.
Thanks again for taking the time to comment on g4js.
So just to remind readers of the question in my original post -
Pjs was never meant to have a user base as a primary concern.
Although we can code in Pjs pretty much like p5js in instance mode, it was primarily created as a way to transform Processing Java Mode syntax in JS syntax so it can run on browsers.
Most folks don’t even realize that when they host a Java Mode sketch in sites like OpenProcessing.org, Pjs is the technology running it behind-the-scenes.
So as long as we’re still using Processing’s Java Mode, the abandoned Pjs is the only viable way to automatically convert basic Java syntax to JS.
Apart from having multi-flavor compatibility, the most tech advise for a Java developer trying out JS is to code in TS (TypeScript):
Which is basically JS w/ enforced datatype at developing time.
Also split the code in JS modules via keywords import & export:
The file “ball.ts” below uses TS language together w/ keywords import & export so it can recognize the p5 & Chamber datatypes:
Thanks for that. I was aware of TypeScript but not looked at it in any detail yet. I would be interested in knowing what programming IDE you use with TypeScript and any advise on organising “Processing / TypeScript / Library development” environment would be appreciated.
As to Pjs, I used it quite a lot when applets went the way of the dodo
Well, I’ve ended up creating a p5js library template repo just to answer that:
After unpacking the downloaded project file:
Double-click file “setup.bat” so it creates the subfolder “node_modules/” and globally installs the TS compiler “tsc”, the local file server “serve”, the p5js library itself, plus its type definitions; all that based on “package.json” contents.
That template project has a “tsconfig.json” file which instructs “tsc” to automatically compile every TS file inside subfolder “src/” and output them into subfolder “dist/”; plus their type definitions into subfolder “typings/”.
In this particular template example I have a class Ball defined in file “dist/ball.mts” which is gonna act as a p5js library addon.
Also a helper “dist/attribute.mts” file which is imported by “dist/ball.mts”.
FYI, “.mts” is a new file extension which explicitly defines it as an ECMAScript Module: 16. Modules
The “tsc” compiler will automatically output “.mts” files as “.mjs” btW:
The last subfolder to discuss is “tests/”, which contains 2 other subfolders “regular/” & “import/”.
In total there are 4 “.js” files as test example sketches on how to consume the “dist/ball.mjs” library.
“tests/regular/sketch.js” is a typical p5js sketch in global mode style.
And “tests/regular/sketch.instance.js” is like the former above, but using instance mode style instead.
It’s super important that a p5js library addon be compatible w/ both global & instance modes.
The other 2 sketches in subfolder “tests/import/” teach how to import the “dist/ball.mjs” library directly in code w/o using a <script> tag in an HTML file:
The “index.html” file loads both sketches from subfolder “tests/regular/”.
It adds the attribute “data-ball-auto-import” to the “dist/ball.mjs” <script> tag.
The library searches all <script> tags for that “data-ball-auto-import” attribute.
When it’s found, it automatically exposes its class Ball to globalThis.
And it also adds the alternative method createBall() to the p5 class.
That’s all for now! Hope it helps you to develop your g4js addon library in TS using ES6 modules:
I’ve taken the time to check the actual G4js source code and unfortunately it’s incompatible w/ p5js instance mode.
That is, G4js can’t be used w/ multiple sketches in the same page unless they’re wrapped up w/ <iframe> tags.
That also keeps out folks who rather prefer coding using p5js instance mode style.
BtW, Shiffman got a YouTube video explaining better how to use it and why use it:
For example the method _renderP2D() from class GPane, p5js library API methods like push(), pop(), translate(), noStroke(), fill(), rect() are all accessed as if they were guaranteed to be always available from the global context, which isn’t the case when p5js is on instance mode:
_renderP2D() {
push()
translate(this._x, this._y)
if (this._visible && this._tabstate != 'closed') {
let _cs = this._localScheme || g4js.scheme()
noStroke()
fill(_cs.black4)
rect(0, 0, this._w, this._h)
}
for (let c of this._children)
if (c._visible) c._renderP2D()
pop()
}
The classGPaneextendsGObject; so in order to fix it, we’ll have to fix GObject 1st:
class GObject {
static corner = 4
constructor(name, x, y, w, h) {
this._name = name
this._children = []
this._parent = undefined
this._x = x
this._y = y
this._w = w
this._h = h
this._visible = true
this._enabled = true
this._localScheme
}
// ...
}
For that we just need to add this extra optional parameter to its constructor: p = p5.instance.
When p5js is on global mode the static property p5.instance holds its reference.
By setting the parameter p optional, global mode users won’t need to pass their sketch’s reference if they choose so.
That would be mandatory for instance mode users only; which is fair:
class GObject {
static CORNER = 4
_children = []
constructor(name, x, y, w, h, p = p5.instance) {
this._p = p
this._name = name
this._x = x
this._y = y
this._w = w
this._h = h
this._parent = this._localScheme = null
this._visible = this._enabled = true
}
// ...
}
With the fix above, class GObject keeps a p5js reference on its property _p, which will be used to access any p5js API from now on.
We’ll have to do the same for your subclass GPane here:
class GPane extends GObject {
// ...
constructor(name, x, y, w, h) {
super(name, x, y, w, h)
this._status = 'closed'
this._timer
this._sortZ = 128
}
// ...
_renderP2D() {
push()
translate(this._x, this._y)
if (this._visible && this._tabstate != 'closed') {
let _cs = this._localScheme || g4js.scheme()
noStroke()
fill(_cs.black4)
rect(0, 0, this._w, this._h)
}
for (let c of this._children)
if (c._visible) c._renderP2D()
pop()
}
// ...
}
@GoToLoop thanks for all this information - a lot to get through and all of it helpful.
I was never a fan of Javascript when it first came out but it has matured a lot since then. I can see both the benefits and disadvantages over strongly typed languages such as Java and C++ and I am enjoying the learning experience. TypeScript will obviously help overcome some of the disadvantages so is on my todo list.
My learning style is to identify projects that interest me then learn the language i.e. Javascript as I implement them. This GUI library provides many opportunities to learn both JS syntax and more advanced features like closures.
Since I am implementing it as part of my learning experience I am in no hurry to finish this library and other project ideas might get slipped in along the way Also there already appears to be a GUI library for p5.js (although I haven’t tried it out) so its not filling a void.
I have been notified that people are still clicking on the link in the first post. I apologise to anyone who does because it is now dead and it no longer possible to edit the link (forum restriction).
This library is now called canvasGUI and has been submitted to p5.js for inclusion in the list of contributed libraries. If you want to find out more about it then you can visit my website and github.