66class 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