CodingTrain / CodingTrain/node-p5-test
Using p5.js in Node runtime
- Lingua principale
- JavaScript
- Stelle
- 7
- Fork
- 1
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Descrizione
## TL;DR: scroll down to the bottom for the templates
---
After studying the source code of [`p5.js`](https://github.com/processing/p5.js), this is what I have gathered so far:
> [These](https://gist.github.com/ccf46106d311bb7dd93fea40c634eece) variables are available in browser `window` and unavailable in node
## p5 Instance Mode
For making p5 work in instance mode I created this template:
```js
// Adapted from:
// ! Heart Curve
// ! Daniel Shiffman
// https://thecodingtrain.com/CodingChallenges/134-heart-curve.html
// https://youtu.be/oUBAi9xQ2X4
// https://editor.p5js.org/codingtrain/sketches/egvieHyt0
const w = 400,
h = 400;
setupWindow(w, h);
const p5 = require("p5");
new p5((p) => {
const heart = [];
let a = 0;
p.setup = () => {
p.createCanvas(w, h);
while (true) {
const r = p.height / 40;
const x = r * 16 * p.pow(p.sin(a), 3);
const y = -r * (13 * p.cos(a) - 5 * p.cos(2 * a) - 2 * p.cos(3 * a) - p.cos(4 * a));
heart.push(p.createVector(x, y));
// So that it stops
if (a > p.TWO_PI) {
break;
}
a += 0.1;
}
p.background(0);
p.translate(p.width / 2, p.height / 2);
p.stroke(255);
p.strokeWeight(2);
p.fill(150, 0, 100);
p.beginShape();
for (let v of heart) {
p.vertex(v.x, v.y);
}
p.endShape();
saveAsPNG(p, "filename");
};
});
async function saveAsPNG(p5Inst, filename = "sketch", exit = true) {
// --- save as png function code ---
}
function setupWindow(w = 100, h = 100) {
// --- setup window function code ---
}
```
**In this way, p5.js can be used in Instance Mode to work with `node-canvas`**
Click here to see the codes for saveAsPNG and setupWindow:
**`saveAsPNG` - Saves the canvas Image to filname using fs**
```js
async function saveAsPNG(p5Inst, filename = "sketch", exit = true) {
const fs = require("fs");
const buffer = p5Inst._renderer.drawingContext.canvas.toBuffer()
await fs.promises.writeFile(filename + ".png", buffer)
if (exit) process.exit(0)
}
```
**`setupWindow` - Add necessary variables to `global` for p5 to run**
```js
function setupWindow(w = 100, h = 100) {
// Import required stuff
const { createCanvas } = require("canvas");
const { JSDOM } = require("jsdom");
const { performance } = require("perf_hooks");
// All the global properties will be available to p5
global.window = global;
// Use JSDOM to simulate DOM methods
const dom = new JSDOM();
global.document = dom.window.document;
const nodeCanvas = createCanvas(w, h);
// p5 will use the methods on nodeCanvas context (overriding JSDOM's getContext function)
dom.window.HTMLCanvasElement.prototype.getContext = (type) => {
return nodeCanvas.getContext(type);
};
// p5 uses window.performance
global.performance = performance;
// window.screen is used to determine displayWidth and displayHeight
// in this case it will be undefined
global.screen = {};
// p5 uses events "load" and "error"
// Using JSDOM equivalent
global.addEventListener = dom.window.addEventListener.bind(dom.window);
global.removeEventListener = dom.window.removeEventListener.bind(dom.window);
// Navigator.userAgent is used by p5 to polyfill methods in older browsers (safari)
global.navigator = { userAgent: "node" };
// when we declare a function in node, it doesn't pollute global scope
// So implicitly write code so that p5 can access these functions on global/window.
// UNCOMMENT NEXT TWO LINES WHEN USING GLOBAL MODE
// global.setup = setup
// global.draw = draw
}
```
## Going further - Global Mode!
This is the template for using p5.js in node with Global Mode:
```js
// Adapted from:
// ! Heart Curve
// ! Daniel Shiffman
// https://thecodingtrain.com/CodingChallenges/134-heart-curve.html
// https://youtu.be/oUBAi9xQ2X4
// https://editor.p5js.org/codingtrain/sketches/egvieHyt0
// width and height to be passed both in createCanvas and in setupWindow
setupWindow(400, 400);
// Note that in global mode even though we don't use the p5 variable, it still needs to be imported.
const p5 = require("p5");
const heart = [];
let a = 0;
function setup() {
createCanvas(400, 400);
}
function draw() {
while (true) {
const r = height / 40;
const x = r * 16 * pow(sin(a), 3);
const y = -r * (13 * cos(a) - 5 * cos(2 * a) - 2 * cos(3 * a) - cos(4 * a));
heart.push(createVector(x, y));
// So that it stops
if (a > TWO_PI) {
break;
}
a += 0.1;
}
background(0);
translate(width / 2, height / 2);
stroke(255);
strokeWeight(2);
fill(150, 0, 100);
beginShape();
for (let v of heart) {
vertex(v.x, v.y);
}
endShape();
// in global mode, p5 is attatched to the window (global in node)
// the third arg stands for whether to exit the process
// in this case, if false is passed, then this sketch will run forever, until manually cancelled (because this is the draw loop)
saveAsPNG(global, "globalimg", true);
}
```
In this case as well, the functions `saveAsPNG` and `setupWindow` should be appended at the end of the file, with the last two lines of `setupWindow` uncommented.
This is the output of the global mode code

## Use these Templates!
To Use these templates, first install these node-modules
`npm i p5 canvas jsdom`
* [Template for using `node-canvas` with `p5.js` in global mode](https://gist.github.com/c59e02991929db850373b3c7d1a858ef)
* [Template for using `node-canvas` with `p5.js` in instance mode](https://gist.github.com/3e898a0acf73f6b58a563981732b4fdc)
Guida per i contributori
Nessuna guida per i contributori indicizzata per questo repository
Direzione di ricerca
Inizia con i template instance-mode e global-mode collegati nell’issue, concentrandoti sugli entry point setupWindow e saveAsPNG e sulle dipendenze p5, canvas e jsdom elencate. L’issue non definisce un file del repository, un test né criteri di accettazione stabiliti, quindi il comportamento previsto del runtime Node supportato dovrebbe essere chiarito prima dell’implementazione.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- javascript, node.js
- Ambito
- backend
- Tipo di issue
- Funzionalità
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Ferma
- Chiarezza
- Da chiarire
- Idoneità per principianti
- 25/100