Skip to content

Commit 5339fa4

Browse files
authored
Merge pull request #1319 from lindapaiste/cleanup/p5utils
Cleanup of P5Util class
2 parents ba2fa93 + 11de63f commit 5339fa4

File tree

1 file changed

+54
-40
lines changed

1 file changed

+54
-40
lines changed

src/utils/p5Utils.js

Lines changed: 54 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,30 @@
66
class P5Util {
77
constructor() {
88
if (typeof window !== "undefined") {
9+
/**
10+
* Store the window as a private property regardless of whether p5 is present.
11+
* Can also set this property by calling method setP5Instance().
12+
* @property {Window | p5 | {p5: p5} | undefined} m_p5Instance
13+
* @private
14+
*/
915
this.m_p5Instance = window;
1016
}
1117
}
1218

1319
/**
14-
* Set p5 instance globally.
15-
* @param {Object} p5Instance
20+
* Set p5 instance globally in order to enable p5 features throughout ml5.
21+
* Call this function with the p5 instance when using p5 in instance mode.
22+
* @param {p5 | {p5: p5}} p5Instance
1623
*/
1724
setP5Instance(p5Instance) {
18-
this.m_p5Instance = p5Instance;
25+
this.m_p5Instance = p5Instance;
1926
}
2027

2128
/**
22-
* This getter will return p5, checking first if it is in
23-
* the window and next if it is in the p5 property of this.m_p5Instance
24-
* @returns {boolean} if it is in p5
29+
* Dynamic getter checks if p5 is loaded and will return undefined if p5 cannot be found,
30+
* or will return an object containing all of the global p5 properties.
31+
* It first checks if p5 is in the window, and then if it is in the p5 property of this.m_p5Instance.
32+
* @returns {p5 | undefined}
2533
*/
2634
get p5Instance() {
2735
if (typeof this.m_p5Instance !== "undefined" &&
@@ -35,75 +43,81 @@ class P5Util {
3543

3644
/**
3745
* This function will check if the p5 is in the environment
38-
* Either it is in the p5Instance mode OR it is in the window
39-
* @returns {boolean} if it is in p5
46+
* Either it is in the p5Instance mode OR it is in the window
47+
* @returns {boolean} if it is in p5
4048
*/
4149
checkP5() {
4250
return !!this.p5Instance;
4351
}
4452

4553
/**
46-
* Convert a canvas to Blob
47-
* @param {HTMLCanvasElement} inputCanvas
48-
* @returns {Blob} blob object
49-
*/
54+
* Convert a canvas to a Blob object.
55+
* @param {HTMLCanvasElement} inputCanvas
56+
* @returns {Promise<Blob>}
57+
*/
5058
/* eslint class-methods-use-this: ["error", { "exceptMethods": ["getBlob"] }] */
5159
getBlob(inputCanvas) {
52-
return new Promise((resolve) => {
60+
return new Promise((resolve, reject) => {
5361
inputCanvas.toBlob((blob) => {
54-
resolve(blob);
62+
if (blob) {
63+
resolve(blob);
64+
} else {
65+
reject(new Error('Canvas could not be converted to Blob.'));
66+
}
5567
});
5668
});
5769
};
5870

5971
/**
60-
* Load image in async way.
61-
* @param {String} url
62-
*/
72+
* Load a p5.Image from a URL in an async way.
73+
* @param {string} url
74+
* @return {Promise<p5.Image>}
75+
*/
6376
loadAsync(url) {
64-
return new Promise((resolve) => {
77+
return new Promise((resolve, reject) => {
6578
this.p5Instance.loadImage(url, (img) => {
6679
resolve(img);
80+
}, () => {
81+
reject(new Error(`Could not load image from url ${url}`));
6782
});
6883
});
6984
};
7085

7186
/**
72-
* convert raw bytes to blob object
73-
* @param {Array} raws
74-
* @param {number} x
75-
* @param {number} y
76-
* @returns {Blob}
77-
*/
78-
async rawToBlob(raws, x, y) {
87+
* convert raw bytes to blob object
88+
* @param {number[] | Uint8ClampedArray | ArrayLike<number>} raws
89+
* @param {number} width
90+
* @param {number} height
91+
* @returns {Promise<Blob>}
92+
*/
93+
async rawToBlob(raws, width, height) {
7994
const arr = Array.from(raws)
8095
const canvas = document.createElement('canvas'); // Consider using offScreenCanvas when it is ready?
8196
const ctx = canvas.getContext('2d');
8297

83-
canvas.width = x;
84-
canvas.height = y;
98+
canvas.width = width;
99+
canvas.height = height;
85100

86-
const imgData = ctx.createImageData(x, y);
87-
const { data } = imgData;
101+
const imgData = ctx.createImageData(width, height);
102+
const {data} = imgData;
88103

89-
for (let i = 0; i < x * y * 4; i += 1 ) data[i] = arr[i];
104+
for (let i = 0; i < width * height * 4; i += 1) data[i] = arr[i];
90105
ctx.putImageData(imgData, 0, 0);
91106

92-
const blob = await this.getBlob(canvas);
93-
return blob;
107+
return this.getBlob(canvas);
94108
};
95109

96110
/**
97-
* Conver Blob to P5.Image
98-
* @param {Blob} blob
99-
* @param {Object} p5Img
100-
*/
111+
* Convert Blob to P5.Image
112+
* @param {Blob} blob
113+
* Note: may want to reject instead of returning null.
114+
* @returns {Promise<p5.Image | null>}
115+
*/
101116
async blobToP5Image(blob) {
102-
if (this.checkP5()) {
103-
const p5Img = await this.loadAsync(URL.createObjectURL(blob));
104-
return p5Img;
117+
if (this.checkP5() && typeof URL !== "undefined") {
118+
return this.loadAsync(URL.createObjectURL(blob));
105119
}
106-
return null;
120+
return null;
107121
};
108122

109123
}

0 commit comments

Comments
 (0)