p5 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/{src → dist}/accessibility/color_namer.js +48 -3
  2. package/{src → dist}/accessibility/describe.js +12 -2
  3. package/{src → dist}/accessibility/gridOutput.js +2 -2
  4. package/dist/accessibility/index.js +60 -0
  5. package/{src → dist}/accessibility/outputs.js +23 -2
  6. package/{src → dist}/accessibility/textOutput.js +2 -2
  7. package/dist/app.js +120 -0
  8. package/{src → dist}/color/color_conversion.js +48 -10
  9. package/{src → dist}/color/color_spaces/hsb.js +3 -1
  10. package/dist/color/creating_reading.js +3 -0
  11. package/dist/color/index.js +13 -0
  12. package/dist/color/p5.Color.culori.js +1 -0
  13. package/dist/color/p5.Color.js +3 -0
  14. package/{src → dist}/color/setting.js +9 -6
  15. package/{src/core/constants.js → dist/constants-tYr0tCl8.js} +284 -132
  16. package/{src → dist}/core/States.js +3 -1
  17. package/dist/core/constants.js +1 -0
  18. package/{src → dist}/core/environment.js +12 -10
  19. package/{src → dist}/core/friendly_errors/browser_errors.js +1 -1
  20. package/{src → dist}/core/friendly_errors/fes_core.js +14 -44
  21. package/{src → dist}/core/friendly_errors/file_errors.js +6 -3
  22. package/dist/core/friendly_errors/index.js +23 -0
  23. package/dist/core/friendly_errors/param_validator.js +5421 -0
  24. package/{src → dist}/core/friendly_errors/sketch_reader.js +50 -4
  25. package/{src → dist}/core/friendly_errors/sketch_verifier.js +6 -6
  26. package/{src → dist}/core/friendly_errors/stacktrace.js +3 -5
  27. package/{src → dist}/core/friendly_errors/validate_params.js +50 -41
  28. package/{src → dist}/core/helpers.js +9 -6
  29. package/dist/core/init.js +105 -0
  30. package/dist/core/internationalization.js +302 -0
  31. package/dist/core/legacy.js +73 -0
  32. package/dist/core/main.js +44 -0
  33. package/dist/core/noop.js +3 -0
  34. package/dist/core/p5.Graphics.js +40 -0
  35. package/dist/core/p5.Renderer.js +11 -0
  36. package/dist/core/p5.Renderer2D.js +44 -0
  37. package/dist/core/reference.js +1 -0
  38. package/dist/core/rendering.js +40 -0
  39. package/{src → dist}/core/structure.js +3 -3
  40. package/{src → dist}/core/transform.js +2 -2
  41. package/{src/color/creating_reading.js → dist/creating_reading-Cr8L2Jnm.js} +841 -13
  42. package/{src → dist}/data/index.js +3 -1
  43. package/{src → dist}/data/local_storage.js +2 -8
  44. package/{src → dist}/dom/dom.js +19 -13
  45. package/dist/dom/index.js +18 -0
  46. package/{src → dist}/dom/p5.Element.js +14 -12
  47. package/{src → dist}/dom/p5.File.js +4 -4
  48. package/{src → dist}/dom/p5.MediaElement.js +10 -4
  49. package/{src → dist}/events/acceleration.js +26 -26
  50. package/{src → dist}/events/index.js +3 -1
  51. package/{src → dist}/events/keyboard.js +14 -12
  52. package/{src → dist}/events/pointer.js +16 -17
  53. package/dist/image/const.js +9 -0
  54. package/{src → dist}/image/filterRenderer2D.js +57 -37
  55. package/{src → dist}/image/filters.js +1 -3
  56. package/dist/image/image.js +40 -0
  57. package/dist/image/index.js +51 -0
  58. package/dist/image/loading_displaying.js +40 -0
  59. package/dist/image/p5.Image.js +11 -0
  60. package/{src → dist}/image/pixels.js +5 -3
  61. package/{src → dist}/io/csv.js +72 -70
  62. package/dist/io/files.js +40 -0
  63. package/dist/io/index.js +51 -0
  64. package/{src → dist}/io/p5.Table.js +6 -6
  65. package/{src → dist}/io/p5.TableRow.js +5 -6
  66. package/{src → dist}/io/p5.XML.js +2 -5
  67. package/{src → dist}/io/utilities.js +1 -1
  68. package/{src/core/p5.Renderer2D.js → dist/main-CAxvgiOV.js} +738 -57
  69. package/{src → dist}/math/Matrices/Matrix.js +10 -8
  70. package/{src → dist}/math/Matrices/MatrixInterface.js +5 -3
  71. package/{src → dist}/math/Matrices/MatrixNumjs.js +12 -26
  72. package/{src → dist}/math/calculation.js +2 -2
  73. package/{src → dist}/math/index.js +6 -3
  74. package/{src → dist}/math/math.js +3 -3
  75. package/{src → dist}/math/noise.js +2 -2
  76. package/{src → dist}/math/p5.Matrix.js +7 -4
  77. package/{src → dist}/math/p5.Vector.js +6 -6
  78. package/{src → dist}/math/random.js +2 -2
  79. package/{src → dist}/math/trigonometry.js +16 -15
  80. package/{src/image/p5.Image.js → dist/p5.Renderer-Swjl9HQO.js} +393 -22
  81. package/dist/rendering-B5TRR7aY.js +24960 -0
  82. package/{src → dist}/shape/2d_primitives.js +18 -17
  83. package/{src → dist}/shape/attributes.js +18 -17
  84. package/{src → dist}/shape/curves.js +2 -2
  85. package/{src → dist}/shape/custom_shapes.js +44 -64
  86. package/{src → dist}/shape/index.js +10 -2
  87. package/{src → dist}/shape/vertex.js +2 -3
  88. package/dist/type/index.js +25 -0
  89. package/{src → dist}/type/lib/Typr.js +76 -94
  90. package/{src → dist}/type/p5.Font.js +37 -63
  91. package/{src → dist}/type/textCore.js +35 -58
  92. package/{src → dist}/type/unicodeRanges.js +3 -1
  93. package/{src → dist}/utilities/conversion.js +2 -2
  94. package/{src → dist}/utilities/index.js +3 -1
  95. package/{src → dist}/utilities/time_date.js +6 -7
  96. package/{src → dist}/utilities/utility_functions.js +2 -2
  97. package/dist/webgl/3d_primitives.js +40 -0
  98. package/{src → dist}/webgl/GeometryBufferCache.js +3 -1
  99. package/{src → dist}/webgl/GeometryBuilder.js +12 -8
  100. package/{src → dist}/webgl/ShaderGenerator.js +79 -82
  101. package/{src → dist}/webgl/ShapeBuilder.js +26 -23
  102. package/dist/webgl/index.js +76 -0
  103. package/{src → dist}/webgl/interaction.js +7 -6
  104. package/dist/webgl/light.js +40 -0
  105. package/{src → dist}/webgl/loading.js +45 -12
  106. package/dist/webgl/material.js +40 -0
  107. package/dist/webgl/p5.Camera.js +40 -0
  108. package/{src → dist}/webgl/p5.DataArray.js +3 -5
  109. package/dist/webgl/p5.Framebuffer.js +40 -0
  110. package/{src → dist}/webgl/p5.Geometry.js +12 -15
  111. package/{src → dist}/webgl/p5.Quat.js +5 -4
  112. package/{src → dist}/webgl/p5.RenderBuffer.js +2 -3
  113. package/dist/webgl/p5.RendererGL.js +40 -0
  114. package/dist/webgl/p5.Shader.js +40 -0
  115. package/dist/webgl/p5.Texture.js +40 -0
  116. package/{src → dist}/webgl/text.js +78 -38
  117. package/lib/p5.esm.js +296 -194
  118. package/lib/p5.js +296 -194
  119. package/lib/p5.min.js +1 -1
  120. package/package.json +17 -17
  121. package/translations/dev.js +6 -6
  122. package/translations/index.js +1 -1
  123. package/types/accessibility/color_namer.d.ts +8 -0
  124. package/types/accessibility/describe.d.ts +184 -0
  125. package/types/accessibility/gridOutput.d.ts +8 -0
  126. package/types/accessibility/outputs.d.ts +235 -0
  127. package/types/accessibility/textOutput.d.ts +8 -0
  128. package/types/color/color_conversion.d.ts +47 -0
  129. package/types/color/creating_reading.d.ts +1348 -0
  130. package/types/color/p5.Color.d.ts +1070 -0
  131. package/types/color/setting.d.ts +2085 -0
  132. package/types/core/constants.d.ts +341 -0
  133. package/types/core/environment.d.ts +668 -0
  134. package/types/core/friendly_errors/fes_core.d.ts +8 -0
  135. package/types/core/friendly_errors/file_errors.d.ts +8 -0
  136. package/types/core/friendly_errors/param_validator.d.ts +30 -0
  137. package/types/core/friendly_errors/sketch_reader.d.ts +8 -0
  138. package/types/core/friendly_errors/stacktrace.d.ts +11 -0
  139. package/types/core/friendly_errors/validate_params.d.ts +8 -0
  140. package/types/core/helpers.d.ts +8 -0
  141. package/types/core/legacy.d.ts +8 -0
  142. package/types/core/main.d.ts +5996 -0
  143. package/types/core/p5.Graphics.d.ts +484 -0
  144. package/types/core/p5.Renderer.d.ts +14 -0
  145. package/types/core/reference.d.ts +8 -0
  146. package/types/core/rendering.d.ts +481 -0
  147. package/types/core/structure.d.ts +492 -0
  148. package/types/core/transform.d.ts +1638 -0
  149. package/types/data/local_storage.d.ts +323 -0
  150. package/types/dom/dom.d.ts +1295 -0
  151. package/types/dom/p5.Element.d.ts +2011 -0
  152. package/types/dom/p5.File.d.ts +13 -0
  153. package/types/dom/p5.MediaElement.d.ts +1249 -0
  154. package/types/events/acceleration.d.ts +193 -0
  155. package/types/events/keyboard.d.ts +499 -0
  156. package/types/events/pointer.d.ts +782 -0
  157. package/types/global.d.ts +5542 -0
  158. package/types/image/filterRenderer2D.d.ts +54 -0
  159. package/types/image/image.d.ts +326 -0
  160. package/types/image/loading_displaying.d.ts +580 -0
  161. package/types/image/p5.Image.d.ts +5882 -0
  162. package/types/image/pixels.d.ts +832 -0
  163. package/types/io/files.d.ts +1447 -0
  164. package/types/io/p5.Table.d.ts +1247 -0
  165. package/types/io/p5.TableRow.d.ts +343 -0
  166. package/types/io/p5.XML.d.ts +1188 -0
  167. package/types/math/Matrices/Matrix.d.ts +1029 -0
  168. package/types/math/Matrices/MatrixNumjs.d.ts +8 -0
  169. package/types/math/calculation.d.ts +923 -0
  170. package/types/math/math.d.ts +90 -0
  171. package/types/math/noise.d.ts +311 -0
  172. package/types/math/p5.Matrix.d.ts +8 -0
  173. package/types/math/p5.Vector.d.ts +3416 -0
  174. package/types/math/random.d.ts +267 -0
  175. package/types/math/trigonometry.d.ts +663 -0
  176. package/types/p5.d.ts +6663 -0
  177. package/types/shape/2d_primitives.d.ts +1033 -0
  178. package/types/shape/attributes.d.ts +466 -0
  179. package/types/shape/curves.d.ts +740 -0
  180. package/types/shape/custom_shapes.d.ts +888 -0
  181. package/types/shape/vertex.d.ts +1141 -0
  182. package/types/type/p5.Font.d.ts +575 -0
  183. package/types/type/textCore.d.ts +1198 -0
  184. package/types/utilities/conversion.d.ts +894 -0
  185. package/types/utilities/time_date.d.ts +295 -0
  186. package/types/utilities/utility_functions.d.ts +587 -0
  187. package/types/webgl/3d_primitives.d.ts +1432 -0
  188. package/types/webgl/ShaderGenerator.d.ts +8 -0
  189. package/types/webgl/interaction.d.ts +371 -0
  190. package/types/webgl/light.d.ts +1184 -0
  191. package/types/webgl/loading.d.ts +481 -0
  192. package/types/webgl/material.d.ts +2656 -0
  193. package/types/webgl/p5.Camera.d.ts +3023 -0
  194. package/types/webgl/p5.DataArray.d.ts +61 -0
  195. package/types/webgl/p5.Framebuffer.d.ts +760 -0
  196. package/types/webgl/p5.Geometry.d.ts +1191 -0
  197. package/types/webgl/p5.Quat.d.ts +45 -0
  198. package/types/webgl/p5.RendererGL.d.ts +234 -0
  199. package/types/webgl/p5.Shader.d.ts +660 -0
  200. package/types/webgl/p5.Texture.d.ts +61 -0
  201. package/types/webgl/text.d.ts +74 -0
  202. package/src/README.md +0 -27
  203. package/src/accessibility/index.js +0 -13
  204. package/src/app.js +0 -61
  205. package/src/color/index.js +0 -9
  206. package/src/color/p5.Color.culori.js +0 -66
  207. package/src/color/p5.Color.js +0 -851
  208. package/src/core/README.md +0 -91
  209. package/src/core/friendly_errors/index.js +0 -13
  210. package/src/core/friendly_errors/param_validator.js +0 -561
  211. package/src/core/init.js +0 -58
  212. package/src/core/internationalization.js +0 -195
  213. package/src/core/legacy.js +0 -29
  214. package/src/core/main.js +0 -689
  215. package/src/core/noop.js +0 -1
  216. package/src/core/p5.Graphics.js +0 -696
  217. package/src/core/p5.Renderer.js +0 -408
  218. package/src/core/reference.js +0 -2060
  219. package/src/core/rendering.js +0 -697
  220. package/src/dom/index.js +0 -11
  221. package/src/image/const.js +0 -6
  222. package/src/image/image.js +0 -731
  223. package/src/image/index.js +0 -15
  224. package/src/image/loading_displaying.js +0 -1431
  225. package/src/io/files.js +0 -2210
  226. package/src/io/index.js +0 -11
  227. package/src/math/README.md +0 -40
  228. package/src/type/index.js +0 -9
  229. package/src/webgl/3d_primitives.js +0 -2741
  230. package/src/webgl/index.js +0 -37
  231. package/src/webgl/light.js +0 -1851
  232. package/src/webgl/material.js +0 -3854
  233. package/src/webgl/p5.Camera.js +0 -4010
  234. package/src/webgl/p5.Framebuffer.js +0 -1865
  235. package/src/webgl/p5.RendererGL.js +0 -2867
  236. package/src/webgl/p5.Shader.js +0 -1505
  237. package/src/webgl/p5.Texture.js +0 -541
  238. package/src/webgl/shaders/basic.frag +0 -6
  239. package/src/webgl/shaders/filters/base.frag +0 -22
  240. package/src/webgl/shaders/filters/base.vert +0 -19
  241. package/src/webgl/shaders/filters/blur.frag +0 -60
  242. package/src/webgl/shaders/filters/default.vert +0 -18
  243. package/src/webgl/shaders/filters/dilate.frag +0 -39
  244. package/src/webgl/shaders/filters/erode.frag +0 -39
  245. package/src/webgl/shaders/filters/gray.frag +0 -16
  246. package/src/webgl/shaders/filters/invert.frag +0 -15
  247. package/src/webgl/shaders/filters/opaque.frag +0 -12
  248. package/src/webgl/shaders/filters/posterize.frag +0 -29
  249. package/src/webgl/shaders/filters/threshold.frag +0 -23
  250. package/src/webgl/shaders/font.frag +0 -216
  251. package/src/webgl/shaders/font.vert +0 -44
  252. package/src/webgl/shaders/imageLight.vert +0 -33
  253. package/src/webgl/shaders/imageLightDiffused.frag +0 -82
  254. package/src/webgl/shaders/imageLightSpecular.frag +0 -134
  255. package/src/webgl/shaders/light.vert +0 -37
  256. package/src/webgl/shaders/light_texture.frag +0 -26
  257. package/src/webgl/shaders/lighting.glsl +0 -227
  258. package/src/webgl/shaders/line.frag +0 -74
  259. package/src/webgl/shaders/line.vert +0 -294
  260. package/src/webgl/shaders/normal.frag +0 -6
  261. package/src/webgl/shaders/normal.vert +0 -72
  262. package/src/webgl/shaders/phong.frag +0 -84
  263. package/src/webgl/shaders/phong.vert +0 -87
  264. package/src/webgl/shaders/point.frag +0 -29
  265. package/src/webgl/shaders/point.vert +0 -19
  266. package/src/webgl/shaders/sphereMapping.frag +0 -26
  267. package/src/webgl/shaders/webgl2Compatibility.glsl +0 -34
package/src/io/files.js DELETED
@@ -1,2210 +0,0 @@
1
- /**
2
- * @module IO
3
- * @submodule Input
4
- * @for p5
5
- * @requires core
6
- */
7
-
8
- import { Renderer } from '../core/p5.Renderer';
9
- import { Graphics } from '../core/p5.Graphics';
10
- import { parse } from './csv';
11
- import { downloadFile, _checkFileExtension } from './utilities';
12
-
13
- class HTTPError extends Error {
14
- status;
15
- response;
16
- ok;
17
- }
18
-
19
- export async function request(path, type){
20
- try {
21
- const res = await fetch(path);
22
-
23
- if (res.ok) {
24
- let data;
25
- switch(type) {
26
- case 'json':
27
- data = await res.json();
28
- break;
29
- case 'text':
30
- data = await res.text();
31
- break;
32
- case 'arrayBuffer':
33
- data = await res.arrayBuffer();
34
- break;
35
- case 'blob':
36
- data = await res.blob();
37
- break;
38
- case 'bytes':
39
- // TODO: Chrome does not implement res.bytes() yet
40
- if(res.bytes){
41
- data = await res.bytes();
42
- }else{
43
- const d = await res.arrayBuffer();
44
- data = new Uint8Array(d);
45
- }
46
- break;
47
- default:
48
- throw new Error('Unsupported response type');
49
- }
50
-
51
- return { data, headers: res.headers };
52
-
53
- } else {
54
- const err = new HTTPError(res.statusText);
55
- err.status = res.status;
56
- err.response = res;
57
- err.ok = false;
58
-
59
- throw err;
60
- }
61
-
62
- } catch(err) {
63
- // Handle both fetch error and HTTP error
64
- if (err instanceof TypeError) {
65
- console.log('You may have encountered a CORS error');
66
- } else if (err instanceof HTTPError) {
67
- console.log('You have encountered a HTTP error');
68
- } else if (err instanceof SyntaxError) {
69
- console.log('There is an error parsing the response to requested data structure');
70
- }
71
-
72
- throw err;
73
- }
74
- }
75
-
76
- function files(p5, fn){
77
- /**
78
- * Loads a JSON file to create an `Object`.
79
- *
80
- * JavaScript Object Notation
81
- * (<a href="https://developer.mozilla.org/en-US/docs/Glossary/JSON" target="_blank">JSON</a>)
82
- * is a standard format for sending data between applications. The format is
83
- * based on JavaScript objects which have keys and values. JSON files store
84
- * data in an object with strings as keys. Values can be strings, numbers,
85
- * Booleans, arrays, `null`, or other objects.
86
- *
87
- * The first parameter, `path`, is a string with the path to the file.
88
- * Paths to local files should be relative, as in
89
- * `loadJSON('assets/data.json')`. URLs such as
90
- * `'https://example.com/data.json'` may be blocked due to browser security.
91
- * The `path` parameter can also be defined as a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)
92
- * object for more advanced usage.
93
- *
94
- * The second parameter, `successCallback`, is optional. If a function is
95
- * passed, as in `loadJSON('assets/data.json', handleData)`, then the
96
- * `handleData()` function will be called once the data loads. The object
97
- * created from the JSON data will be passed to `handleData()` as its only argument.
98
- * The return value of the `handleData()` function will be used as the final return
99
- * value of `loadJSON('assets/data.json', handleData)`.
100
- *
101
- * The third parameter, `failureCallback`, is also optional. If a function is
102
- * passed, as in `loadJSON('assets/data.json', handleData, handleFailure)`,
103
- * then the `handleFailure()` function will be called if an error occurs while
104
- * loading. The `Error` object will be passed to `handleFailure()` as its only
105
- * argument. The return value of the `handleFailure()` function will be used as the
106
- * final return value of `loadJSON('assets/data.json', handleData, handleFailure)`.
107
- *
108
- * This function returns a `Promise` and should be used in an `async` setup with
109
- * `await`. See the examples for the usage syntax.
110
- *
111
- * @method loadJSON
112
- * @param {String|Request} path path of the JSON file to be loaded.
113
- * @param {Function} [successCallback] function to call once the data is loaded. Will be passed the object.
114
- * @param {Function} [errorCallback] function to call if the data fails to load. Will be passed an `Error` event object.
115
- * @return {Promise<Object>} object containing the loaded data.
116
- *
117
- * @example
118
- *
119
- * <div>
120
- * <code>
121
- * let myData;
122
- *
123
- * async function setup() {
124
- * myData = await loadJSON('assets/data.json');
125
- * createCanvas(100, 100);
126
- *
127
- * background(200);
128
- *
129
- * // Style the circle.
130
- * fill(myData.color);
131
- * noStroke();
132
- *
133
- * // Draw the circle.
134
- * circle(myData.x, myData.y, myData.d);
135
- *
136
- * describe('A pink circle on a gray background.');
137
- * }
138
- * </code>
139
- * </div>
140
- *
141
- * <div>
142
- * <code>
143
- * let myData;
144
- *
145
- * async function setup() {
146
- * myData = await loadJSON('assets/data.json');
147
- * createCanvas(100, 100);
148
- *
149
- * background(200);
150
- *
151
- * // Create a p5.Color object and make it transparent.
152
- * let c = color(myData.color);
153
- * c.setAlpha(80);
154
- *
155
- * // Style the circles.
156
- * fill(c);
157
- * noStroke();
158
- *
159
- * // Iterate over the myData.bubbles array.
160
- * for (let b of myData.bubbles) {
161
- * // Draw a circle for each bubble.
162
- * circle(b.x, b.y, b.d);
163
- * }
164
- *
165
- * describe('Several pink bubbles floating in a blue sky.');
166
- * }
167
- * </code>
168
- * </div>
169
- *
170
- * <div>
171
- * <code>
172
- * let myData;
173
- *
174
- * async function setup() {
175
- * myData = await loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson');
176
- * createCanvas(100, 100);
177
- *
178
- * background(200);
179
- *
180
- * // Get data about the most recent earthquake.
181
- * let quake = myData.features[0].properties;
182
- *
183
- * // Draw a circle based on the earthquake's magnitude.
184
- * circle(50, 50, quake.mag * 10);
185
- *
186
- * // Style the text.
187
- * textAlign(LEFT, CENTER);
188
- * textFont('Courier New');
189
- * textSize(11);
190
- *
191
- * // Display the earthquake's location.
192
- * text(quake.place, 5, 80, 100);
193
- *
194
- * describe(`A white circle on a gray background. The text "${quake.place}" is written beneath the circle.`);
195
- * }
196
- * </code>
197
- * </div>
198
- *
199
- * <div>
200
- * <code>
201
- * let bigQuake;
202
- *
203
- * // Load the GeoJSON and preprocess it.
204
- * async function setup() {
205
- * await loadJSON(
206
- * 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson',
207
- * handleData
208
- * );
209
- *
210
- * createCanvas(100, 100);
211
- *
212
- * background(200);
213
- *
214
- * // Draw a circle based on the earthquake's magnitude.
215
- * circle(50, 50, bigQuake.mag * 10);
216
- *
217
- * // Style the text.
218
- * textAlign(LEFT, CENTER);
219
- * textFont('Courier New');
220
- * textSize(11);
221
- *
222
- * // Display the earthquake's location.
223
- * text(bigQuake.place, 5, 80, 100);
224
- *
225
- * describe(`A white circle on a gray background. The text "${bigQuake.place}" is written beneath the circle.`);
226
- * }
227
- *
228
- * // Find the biggest recent earthquake.
229
- * function handleData(data) {
230
- * let maxMag = 0;
231
- * // Iterate over the earthquakes array.
232
- * for (let quake of data.features) {
233
- * // Reassign bigQuake if a larger
234
- * // magnitude quake is found.
235
- * if (quake.properties.mag > maxMag) {
236
- * bigQuake = quake.properties;
237
- * }
238
- * }
239
- * }
240
- * </code>
241
- * </div>
242
- *
243
- * <div>
244
- * <code>
245
- * let bigQuake;
246
- *
247
- * // Load the GeoJSON and preprocess it.
248
- * async function setup() {
249
- * await loadJSON(
250
- * 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson',
251
- * handleData,
252
- * handleError
253
- * );
254
- *
255
- * createCanvas(100, 100);
256
- *
257
- * background(200);
258
- *
259
- * // Draw a circle based on the earthquake's magnitude.
260
- * circle(50, 50, bigQuake.mag * 10);
261
- *
262
- * // Style the text.
263
- * textAlign(LEFT, CENTER);
264
- * textFont('Courier New');
265
- * textSize(11);
266
- *
267
- * // Display the earthquake's location.
268
- * text(bigQuake.place, 5, 80, 100);
269
- *
270
- * describe(`A white circle on a gray background. The text "${bigQuake.place}" is written beneath the circle.`);
271
- * }
272
- *
273
- * // Find the biggest recent earthquake.
274
- * function handleData(data) {
275
- * let maxMag = 0;
276
- * // Iterate over the earthquakes array.
277
- * for (let quake of data.features) {
278
- * // Reassign bigQuake if a larger
279
- * // magnitude quake is found.
280
- * if (quake.properties.mag > maxMag) {
281
- * bigQuake = quake.properties;
282
- * }
283
- * }
284
- * }
285
- *
286
- * // Log any errors to the console.
287
- * function handleError(error) {
288
- * console.log('Oops!', error);
289
- * }
290
- * </code>
291
- * </div>
292
- */
293
- fn.loadJSON = async function (path, successCallback, errorCallback) {
294
- // p5._validateParameters('loadJSON', arguments);
295
-
296
- try{
297
- const { data } = await request(path, 'json');
298
- if (successCallback) return successCallback(data);
299
- return data;
300
- } catch(err) {
301
- p5._friendlyFileLoadError(5, path);
302
- if(errorCallback) {
303
- return errorCallback(err);
304
- } else {
305
- throw err;
306
- }
307
- }
308
- };
309
-
310
- /**
311
- * Loads a text file to create an `Array`.
312
- *
313
- * The first parameter, `path`, is always a string with the path to the file.
314
- * Paths to local files should be relative, as in
315
- * `loadStrings('assets/data.txt')`. URLs such as
316
- * `'https://example.com/data.txt'` may be blocked due to browser security.
317
- * The `path` parameter can also be defined as a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)
318
- * object for more advanced usage.
319
- *
320
- * The second parameter, `successCallback`, is optional. If a function is
321
- * passed, as in `loadStrings('assets/data.txt', handleData)`, then the
322
- * `handleData()` function will be called once the data loads. The array
323
- * created from the text data will be passed to `handleData()` as its only
324
- * argument. The return value of the `handleData()` function will be used as
325
- * the final return value of `loadStrings('assets/data.txt', handleData)`.
326
- *
327
- * The third parameter, `failureCallback`, is also optional. If a function is
328
- * passed, as in `loadStrings('assets/data.txt', handleData, handleFailure)`,
329
- * then the `handleFailure()` function will be called if an error occurs while
330
- * loading. The `Error` object will be passed to `handleFailure()` as its only
331
- * argument. The return value of the `handleFailure()` function will be used as
332
- * the final return value of `loadStrings('assets/data.txt', handleData, handleFailure)`.
333
- *
334
- * This function returns a `Promise` and should be used in an `async` setup with
335
- * `await`. See the examples for the usage syntax.
336
- *
337
- * @method loadStrings
338
- * @param {String|Request} path path of the text file to be loaded.
339
- * @param {Function} [successCallback] function to call once the data is
340
- * loaded. Will be passed the array.
341
- * @param {Function} [errorCallback] function to call if the data fails to
342
- * load. Will be passed an `Error` event
343
- * object.
344
- * @return {Promise<String[]>} new array containing the loaded text.
345
- *
346
- * @example
347
- *
348
- * <div>
349
- * <code>
350
- * let myData;
351
- *
352
- * async function setup() {
353
- * myData = await loadStrings('assets/test.txt');
354
- *
355
- * createCanvas(100, 100);
356
- *
357
- * background(200);
358
- *
359
- * // Select a random line from the text.
360
- * let phrase = random(myData);
361
- *
362
- * // Style the text.
363
- * textAlign(LEFT, CENTER);
364
- * textFont('Courier New');
365
- * textSize(12);
366
- *
367
- * // Display the text.
368
- * text(phrase, 10, 50, 90);
369
- *
370
- * describe(`The text "${phrase}" written in black on a gray background.`);
371
- * }
372
- * </code>
373
- * </div>
374
- *
375
- * <div>
376
- * <code>
377
- * let lastLine;
378
- *
379
- * // Load the text and preprocess it.
380
- * async function setup() {
381
- * await loadStrings('assets/test.txt', handleData);
382
- *
383
- * createCanvas(100, 100);
384
- *
385
- * background(200);
386
- *
387
- * // Style the text.
388
- * textAlign(LEFT, CENTER);
389
- * textFont('Courier New');
390
- * textSize(12);
391
- *
392
- * // Display the text.
393
- * text(lastLine, 10, 50, 90);
394
- *
395
- * describe('The text "I talk like an orange" written in black on a gray background.');
396
- * }
397
- *
398
- * // Select the last line from the text.
399
- * function handleData(data) {
400
- * lastLine = data[data.length - 1];
401
- * }
402
- * </code>
403
- * </div>
404
- *
405
- * <div>
406
- * <code>
407
- * let lastLine;
408
- *
409
- * // Load the text and preprocess it.
410
- * async function setup() {
411
- * await loadStrings('assets/test.txt', handleData, handleError);
412
- *
413
- * createCanvas(100, 100);
414
- *
415
- * background(200);
416
- *
417
- * // Style the text.
418
- * textAlign(LEFT, CENTER);
419
- * textFont('Courier New');
420
- * textSize(12);
421
- *
422
- * // Display the text.
423
- * text(lastLine, 10, 50, 90);
424
- *
425
- * describe('The text "I talk like an orange" written in black on a gray background.');
426
- * }
427
- *
428
- * // Select the last line from the text.
429
- * function handleData(data) {
430
- * lastLine = data[data.length - 1];
431
- * }
432
- *
433
- * // Log any errors to the console.
434
- * function handleError(error) {
435
- * console.error('Oops!', error);
436
- * }
437
- * </code>
438
- * </div>
439
- */
440
- fn.loadStrings = async function (path, successCallback, errorCallback) {
441
- // p5._validateParameters('loadStrings', arguments);
442
-
443
- try{
444
- let { data } = await request(path, 'text');
445
- data = data.split(/\r?\n/);
446
-
447
- if (successCallback) return successCallback(data);
448
- return data;
449
- } catch(err) {
450
- p5._friendlyFileLoadError(3, path);
451
- if(errorCallback) {
452
- return errorCallback(err);
453
- } else {
454
- throw err;
455
- }
456
- }
457
- };
458
-
459
- /**
460
- * Reads the contents of a file or URL and creates a <a href="#/p5.Table">p5.Table</a> object with
461
- * its values. If a file is specified, it must be located in the sketch's
462
- * "data" folder. The filename parameter can also be a URL to a file found
463
- * online. By default, the file is assumed to be comma-separated (in CSV
464
- * format). Table only looks for a header row if the 'header' option is
465
- * included.
466
- *
467
- * This function returns a `Promise` and should be used in an `async` setup with
468
- * `await`. See the examples for the usage syntax.
469
- *
470
- * All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB.
471
- *
472
- * @method loadTable
473
- * @deprecated p5.Table will be removed in a future version of p5.js to make way for a new, friendlier version :)
474
- * @param {String|Request} filename name of the file or URL to load
475
- * @param {String} [separator] the separator character used by the file, defaults to `','`
476
- * @param {String} [header] "header" to indicate table has header row
477
- * @param {Function} [callback] function to be executed after
478
- * <a href="#/p5/loadTable">loadTable()</a> completes. On success, the
479
- * <a href="#/p5.Table">Table</a> object is passed in as the
480
- * first argument.
481
- * @param {Function} [errorCallback] function to be executed if
482
- * there is an error, response is passed
483
- * in as first argument
484
- * @return {Promise<Object>} <a href="#/p5.Table">Table</a> object containing data
485
- *
486
- * @example
487
- * <div class='norender'>
488
- * <code>
489
- * let table;
490
- *
491
- * async function setup() {
492
- * // Create a 200x200 canvas
493
- * createCanvas(200, 200);
494
- *
495
- * // Load the CSV file with a header row
496
- * table = await loadTable('assets/mammals.csv', ',', 'header');
497
- *
498
- * // Get the second row (index 1)
499
- * let row = table.getRow(1);
500
- *
501
- * // Set text properties
502
- * fill(0); // Set text color to black
503
- * textSize(16); // Adjust text size as needed
504
- *
505
- * // Display each column value in the row on the canvas.
506
- * // Using an offset for y-position so each value appears on a new line.
507
- * for (let c = 0; c < table.getColumnCount(); c++) {
508
- * text(row.getString(c), 10, 30 + c * 20);
509
- * }
510
- * }
511
- * </code>
512
- * </div>
513
- */
514
- fn.loadTable = async function (path, separator, header, successCallback, errorCallback) {
515
- if(typeof arguments[arguments.length-1] === 'function'){
516
- if(typeof arguments[arguments.length-2] === 'function'){
517
- successCallback = arguments[arguments.length-2];
518
- errorCallback = arguments[arguments.length-1];
519
- }else{
520
- successCallback = arguments[arguments.length-1];
521
- }
522
- }
523
-
524
- if(typeof separator !== 'string') separator = ',';
525
- if(typeof header === 'function') header = false;
526
-
527
- try{
528
- let { data } = await request(path, 'text');
529
-
530
- let ret = new p5.Table();
531
- data = parse(data, {
532
- separator
533
- });
534
-
535
- if(header){
536
- ret.columns = data.shift();
537
- }else{
538
- ret.columns = Array(data[0].length).fill(null);
539
- }
540
-
541
- data.forEach((line) => {
542
- const row = new p5.TableRow(line);
543
- ret.addRow(row);
544
- });
545
-
546
- if (successCallback) {
547
- return successCallback(ret);
548
- } else {
549
- return ret;
550
- }
551
- } catch(err) {
552
- p5._friendlyFileLoadError(2, path);
553
- if(errorCallback) {
554
- return errorCallback(err);
555
- } else {
556
- throw err;
557
- }
558
- }
559
- };
560
-
561
- /**
562
- * Loads an XML file to create a <a href="#/p5.XML">p5.XML</a> object.
563
- *
564
- * Extensible Markup Language
565
- * (<a href="https://developer.mozilla.org/en-US/docs/Web/XML/XML_introduction" target="_blank">XML</a>)
566
- * is a standard format for sending data between applications. Like HTML, the
567
- * XML format is based on tags and attributes, as in
568
- * `&lt;time units="s"&gt;1234&lt;/time&gt;`.
569
- *
570
- * The first parameter, `path`, is always a string with the path to the file.
571
- * Paths to local files should be relative, as in
572
- * `loadXML('assets/data.xml')`. URLs such as `'https://example.com/data.xml'`
573
- * may be blocked due to browser security. The `path` parameter can also be defined
574
- * as a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)
575
- * object for more advanced usage.
576
- *
577
- * The second parameter, `successCallback`, is optional. If a function is
578
- * passed, as in `loadXML('assets/data.xml', handleData)`, then the
579
- * `handleData()` function will be called once the data loads. The
580
- * <a href="#/p5.XML">p5.XML</a> object created from the data will be passed
581
- * to `handleData()` as its only argument. The return value of the `handleData()`
582
- * function will be used as the final return value of `loadXML('assets/data.xml', handleData)`.
583
- *
584
- * The third parameter, `failureCallback`, is also optional. If a function is
585
- * passed, as in `loadXML('assets/data.xml', handleData, handleFailure)`, then
586
- * the `handleFailure()` function will be called if an error occurs while
587
- * loading. The `Error` object will be passed to `handleFailure()` as its only
588
- * argument. The return value of the `handleFailure()` function will be used as the
589
- * final return value of `loadXML('assets/data.xml', handleData, handleFailure)`.
590
- *
591
- * This function returns a `Promise` and should be used in an `async` setup with
592
- * `await`. See the examples for the usage syntax.
593
- *
594
- * @method loadXML
595
- * @param {String|Request} path path of the XML file to be loaded.
596
- * @param {Function} [successCallback] function to call once the data is
597
- * loaded. Will be passed the
598
- * <a href="#/p5.XML">p5.XML</a> object.
599
- * @param {Function} [errorCallback] function to call if the data fails to
600
- * load. Will be passed an `Error` event
601
- * object.
602
- * @return {Promise<p5.XML>} XML data loaded into a <a href="#/p5.XML">p5.XML</a>
603
- * object.
604
- *
605
- * @example
606
- * <div>
607
- * <code>
608
- * let myXML;
609
- *
610
- * // Load the XML and create a p5.XML object.
611
- * async function setup() {
612
- * myXML = await loadXML('assets/animals.xml');
613
- *
614
- * createCanvas(100, 100);
615
- *
616
- * background(200);
617
- *
618
- * // Get an array with all mammal tags.
619
- * let mammals = myXML.getChildren('mammal');
620
- *
621
- * // Style the text.
622
- * textAlign(LEFT, CENTER);
623
- * textFont('Courier New');
624
- * textSize(14);
625
- *
626
- * // Iterate over the mammals array.
627
- * for (let i = 0; i < mammals.length; i += 1) {
628
- *
629
- * // Calculate the y-coordinate.
630
- * let y = (i + 1) * 25;
631
- *
632
- * // Get the mammal's common name.
633
- * let name = mammals[i].getContent();
634
- *
635
- * // Display the mammal's name.
636
- * text(name, 20, y);
637
- * }
638
- *
639
- * describe(
640
- * 'The words "Goat", "Leopard", and "Zebra" written on three separate lines. The text is black on a gray background.'
641
- * );
642
- * }
643
- * </code>
644
- * </div>
645
- *
646
- * <div>
647
- * <code>
648
- * let lastMammal;
649
- *
650
- * // Load the XML and create a p5.XML object.
651
- * async function setup() {
652
- * await loadXML('assets/animals.xml', handleData);
653
- *
654
- * createCanvas(100, 100);
655
- *
656
- * background(200);
657
- *
658
- * // Style the text.
659
- * textAlign(CENTER, CENTER);
660
- * textFont('Courier New');
661
- * textSize(16);
662
- *
663
- * // Display the content of the last mammal element.
664
- * text(lastMammal, 50, 50);
665
- *
666
- * describe('The word "Zebra" written in black on a gray background.');
667
- * }
668
- *
669
- * // Get the content of the last mammal element.
670
- * function handleData(data) {
671
- * // Get an array with all mammal elements.
672
- * let mammals = data.getChildren('mammal');
673
- *
674
- * // Get the content of the last mammal.
675
- * lastMammal = mammals[mammals.length - 1].getContent();
676
- * }
677
- * </code>
678
- * </div>
679
- *
680
- * <div>
681
- * <code>
682
- * let lastMammal;
683
- *
684
- * // Load the XML and preprocess it.
685
- * async function setup() {
686
- * await loadXML('assets/animals.xml', handleData, handleError);
687
- *
688
- * createCanvas(100, 100);
689
- *
690
- * background(200);
691
- *
692
- * // Style the text.
693
- * textAlign(CENTER, CENTER);
694
- * textFont('Courier New');
695
- * textSize(16);
696
- *
697
- * // Display the content of the last mammal element.
698
- * text(lastMammal, 50, 50);
699
- *
700
- * describe('The word "Zebra" written in black on a gray background.');
701
- * }
702
- *
703
- * // Get the content of the last mammal element.
704
- * function handleData(data) {
705
- * // Get an array with all mammal elements.
706
- * let mammals = data.getChildren('mammal');
707
- *
708
- * // Get the content of the last mammal.
709
- * lastMammal = mammals[mammals.length - 1].getContent();
710
- * }
711
- *
712
- * // Log any errors to the console.
713
- * function handleError(error) {
714
- * console.error('Oops!', error);
715
- * }
716
- * </code>
717
- * </div>
718
- */
719
- fn.loadXML = async function (path, successCallback, errorCallback) {
720
- try{
721
- const parser = new DOMParser();
722
-
723
- let { data } = await request(path, 'text');
724
- const parsedDOM = parser.parseFromString(data, 'application/xml');
725
- data = new p5.XML(parsedDOM);
726
-
727
- if (successCallback) return successCallback(data);
728
- return data;
729
- } catch(err) {
730
- p5._friendlyFileLoadError(1, path);
731
- if(errorCallback) {
732
- return errorCallback(err);
733
- } else {
734
- throw err;
735
- }
736
- }
737
- };
738
-
739
- /**
740
- * This method is suitable for fetching files up to size of 64MB.
741
- *
742
- * @method loadBytes
743
- * @param {String|Request} file name of the file or URL to load
744
- * @param {Function} [callback] function to be executed after <a href="#/p5/loadBytes">loadBytes()</a>
745
- * completes
746
- * @param {Function} [errorCallback] function to be executed if there
747
- * is an error
748
- * @returns {Promise<Uint8Array>} a Uint8Array containing the loaded buffer
749
- *
750
- * @example
751
- *
752
- * <div>
753
- * <code>
754
- * let data;
755
- *
756
- * async function setup() {
757
- * createCanvas(100, 100); // Create a canvas
758
- * data = await loadBytes('assets/mammals.xml'); // Load the bytes from the XML file
759
- *
760
- * background(255); // Set a white background
761
- * fill(0); // Set text color to black
762
- *
763
- * // Display the first 5 byte values on the canvas in hexadecimal format
764
- * for (let i = 0; i < 5; i++) {
765
- * let byteHex = data[i].toString(16);
766
- * text(byteHex, 10, 18 * (i + 1)); // Adjust spacing as needed
767
- * }
768
- *
769
- * describe('no image displayed, displays first 5 bytes of mammals.xml in hexadecimal format');
770
- * }
771
- * </code>
772
- * </div>
773
- */
774
-
775
- fn.loadBytes = async function (path, successCallback, errorCallback) {
776
- try{
777
- let { data } = await request(path, 'arrayBuffer');
778
- data = new Uint8Array(data);
779
- if (successCallback) return successCallback(data);
780
- return data;
781
- } catch(err) {
782
- p5._friendlyFileLoadError(6, path);
783
- if(errorCallback) {
784
- return errorCallback(err);
785
- } else {
786
- throw err;
787
- }
788
- }
789
- };
790
-
791
- /**
792
- * Loads a file at the given path as a Blob, then returns the resulting data or
793
- * passes it to a success callback function, if provided. On load, this function
794
- * returns a `Promise` that resolves to a Blob containing the file data.
795
- *
796
- * @method loadBlob
797
- * @param {String|Request} path - The path or Request object pointing to the file
798
- * you want to load.
799
- * @param {Function} [successCallback] - Optional. A function to be called if the
800
- * file successfully loads, receiving the
801
- * resulting Blob as its only argument.
802
- * @param {Function} [errorCallback] - Optional. A function to be called if an
803
- * error occurs during loading; receives the
804
- * error object as its only argument.
805
- * @returns {Promise<Blob>} A promise that resolves with the loaded Blob.
806
- *
807
- * @example
808
- * <div>
809
- * <code>
810
- * let myBlob;
811
- *
812
- * async function setup() {
813
- * createCanvas(200, 200);
814
- * background(220);
815
- * try {
816
- * // 1. Load an image file as a Blob.
817
- * myBlob = await loadBlob('assets/flower-1.png');
818
- *
819
- * // 2. Convert the Blob into an object URL.
820
- * const objectUrl = URL.createObjectURL(myBlob);
821
- *
822
- * // 3. Load that object URL into a p5.Image.
823
- * loadImage(objectUrl, (img) => {
824
- * // 4. Display the loaded image.
825
- * image(img, 0, 0, width, height);
826
- * });
827
- * } catch (err) {
828
- * console.error('Error loading blob:', err);
829
- * }
830
- * }
831
- * </code>
832
- * </div>
833
- */
834
- fn.loadBlob = async function(path, successCallback, errorCallback) {
835
- try{
836
- const { data } = await request(path, 'blob');
837
- if (successCallback) return successCallback(data);
838
- return data;
839
- } catch(err) {
840
- if(errorCallback) {
841
- return errorCallback(err);
842
- } else {
843
- throw err;
844
- }
845
- }
846
- };
847
-
848
- /**
849
- * Method for executing an HTTP GET request. If data type is not specified,
850
- * it will default to `'text'`. This is equivalent to
851
- * calling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return
852
- * a Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer
853
- * which can be used to initialize typed arrays (such as Uint8Array).
854
- *
855
- * @method httpGet
856
- * @param {String|Request} path name of the file or url to load
857
- * @param {String} [datatype] "json", "jsonp", "binary", "arrayBuffer",
858
- * "xml", or "text"
859
- * @param {Function} [callback] function to be executed after
860
- * <a href="#/p5/httpGet">httpGet()</a> completes, data is passed in
861
- * as first argument
862
- * @param {Function} [errorCallback] function to be executed if
863
- * there is an error, response is passed
864
- * in as first argument
865
- * @return {Promise} A promise that resolves with the data when the operation
866
- * completes successfully or rejects with the error after
867
- * one occurs.
868
- * @example
869
- * <div class='norender'><code>
870
- * // Examples use USGS Earthquake API:
871
- * // https://earthquake.usgs.gov/fdsnws/event/1/#methods
872
- * let earthquakes;
873
- * async function setup() {
874
- * // Get the most recent earthquake in the database
875
- * let url =
876
- 'https://earthquake.usgs.gov/fdsnws/event/1/query?' +
877
- * 'format=geojson&limit=1&orderby=time';
878
- * earthquakes = await httpGet(url, 'json');
879
- * }
880
- *
881
- * function draw() {
882
- * if (!earthquakes) {
883
- * // Wait until the earthquake data has loaded before drawing.
884
- * return;
885
- * }
886
- * background(200);
887
- * // Get the magnitude and name of the earthquake out of the loaded JSON
888
- * let earthquakeMag = earthquakes.features[0].properties.mag;
889
- * let earthquakeName = earthquakes.features[0].properties.place;
890
- * ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);
891
- * textAlign(CENTER);
892
- * text(earthquakeName, 0, height - 30, width, 30);
893
- * noLoop();
894
- * }
895
- * </code></div>
896
- */
897
- /**
898
- * @method httpGet
899
- * @param {String|Request} path
900
- * @param {Function} callback
901
- * @param {Function} [errorCallback]
902
- * @return {Promise}
903
- */
904
- fn.httpGet = async function (path, datatype='text', successCallback, errorCallback) {
905
- // p5._validateParameters('httpGet', arguments);
906
-
907
- if (typeof datatype === 'function') {
908
- errorCallback = successCallback;
909
- successCallback = datatype;
910
- datatype = 'text';
911
- }
912
-
913
- // This is like a more primitive version of the other load functions.
914
- // If the user wanted to customize more behavior, pass in Request to path.
915
-
916
- return this.httpDo(path, 'GET', datatype, successCallback, errorCallback);
917
- };
918
-
919
- /**
920
- * Method for executing an HTTP POST request. If data type is not specified,
921
- * it will default to `'text'`. This is equivalent to
922
- * calling <code>httpDo(path, 'POST')</code>.
923
- *
924
- * @method httpPost
925
- * @param {String|Request} path name of the file or url to load
926
- * @param {Object|Boolean} [data] param data passed sent with request
927
- * @param {String} [datatype] "json", "jsonp", "xml", or "text".
928
- * If omitted, <a href="#/p5/httpPost">httpPost()</a> will guess.
929
- * @param {Function} [callback] function to be executed after
930
- * <a href="#/p5/httpPost">httpPost()</a> completes, data is passed in
931
- * as first argument
932
- * @param {Function} [errorCallback] function to be executed if
933
- * there is an error, response is passed
934
- * in as first argument
935
- * @return {Promise} A promise that resolves with the data when the operation
936
- * completes successfully or rejects with the error after
937
- * one occurs.
938
- *
939
- * @example
940
- * <div>
941
- * <code>
942
- * // Examples use jsonplaceholder.typicode.com for a Mock Data API
943
- *
944
- * let url = 'https://jsonplaceholder.typicode.com/posts';
945
- * let postData = { userId: 1, title: 'p5 Clicked!', body: 'p5.js is very cool.' };
946
- *
947
- * function setup() {
948
- * createCanvas(100, 100);
949
- * background(200);
950
- * }
951
- *
952
- * function mousePressed() {
953
- * httpPost(url, 'json', postData, function(result) {
954
- * strokeWeight(2);
955
- * text(result.body, mouseX, mouseY);
956
- * });
957
- * }
958
- * </code>
959
- * </div>
960
- *
961
- * <div><code>
962
- * let url = 'ttps://invalidURL'; // A bad URL that will cause errors
963
- * let postData = { title: 'p5 Clicked!', body: 'p5.js is very cool.' };
964
- *
965
- * function setup() {
966
- * createCanvas(100, 100);
967
- * background(200);
968
- * }
969
- *
970
- * function mousePressed() {
971
- * httpPost(
972
- * url,
973
- * 'json',
974
- * postData,
975
- * function(result) {
976
- * // ... won't be called
977
- * },
978
- * function(error) {
979
- * strokeWeight(2);
980
- * text(error.toString(), mouseX, mouseY);
981
- * }
982
- * );
983
- * }
984
- * </code></div>
985
- */
986
- /**
987
- * @method httpPost
988
- * @param {String|Request} path
989
- * @param {Object|Boolean} data
990
- * @param {Function} [callback]
991
- * @param {Function} [errorCallback]
992
- * @return {Promise}
993
- */
994
- /**
995
- * @method httpPost
996
- * @param {String|Request} path
997
- * @param {Function} [callback]
998
- * @param {Function} [errorCallback]
999
- * @return {Promise}
1000
- */
1001
- fn.httpPost = async function (path, data, datatype='text', successCallback, errorCallback) {
1002
- // p5._validateParameters('httpPost', arguments);
1003
-
1004
- // This behave similarly to httpGet and additional options should be passed
1005
- // as a `Request`` to path. Both method and body will be overridden.
1006
- // Will try to infer correct Content-Type for given data.
1007
-
1008
- if (typeof data === 'function') {
1009
- // Assume both data and datatype are functions as data should not be function
1010
- successCallback = data;
1011
- errorCallback = datatype;
1012
- data = undefined;
1013
- datatype = 'text';
1014
-
1015
- } else if (typeof datatype === 'function') {
1016
- // Data is provided but not datatype\
1017
- errorCallback = successCallback;
1018
- successCallback = datatype;
1019
- datatype = 'text';
1020
- }
1021
-
1022
- let reqData = data;
1023
- let contentType = 'text/plain';
1024
- // Normalize data
1025
- if(data instanceof p5.XML) {
1026
- reqData = data.serialize();
1027
- contentType = 'application/xml';
1028
-
1029
- } else if(data instanceof p5.Image) {
1030
- reqData = await data.toBlob();
1031
- contentType = 'image/png';
1032
-
1033
- } else if (typeof data === 'object') {
1034
- reqData = JSON.stringify(data);
1035
- contentType = 'application/json';
1036
- }
1037
-
1038
- const requestOptions = {
1039
- method: 'POST',
1040
- body: reqData,
1041
- headers: {
1042
- 'Content-Type': contentType
1043
- }
1044
- };
1045
-
1046
- if (reqData) {
1047
- requestOptions.body = reqData;
1048
- }
1049
-
1050
- const req = new Request(path, requestOptions);
1051
-
1052
- return this.httpDo(req, 'POST', datatype, successCallback, errorCallback);
1053
- };
1054
-
1055
- /**
1056
- * Method for executing an HTTP request. If data type is not specified,
1057
- * it will default to `'text'`.
1058
- *
1059
- * This function is meant for more advanced usage of HTTP requests in p5.js. It is
1060
- * best used when a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)
1061
- * object is passed to the `path` parameter.
1062
- *
1063
- * This method is suitable for fetching files up to size of 64MB when "GET" is used.
1064
- *
1065
- * @method httpDo
1066
- * @param {String|Request} path name of the file or url to load
1067
- * @param {String} [method] either "GET", "POST", "PUT", "DELETE",
1068
- * or other HTTP request methods
1069
- * @param {String} [datatype] "json", "jsonp", "xml", or "text"
1070
- * @param {Object} [data] param data passed sent with request
1071
- * @param {Function} [callback] function to be executed after
1072
- * <a href="#/p5/httpGet">httpGet()</a> completes, data is passed in
1073
- * as first argument
1074
- * @param {Function} [errorCallback] function to be executed if
1075
- * there is an error, response is passed
1076
- * in as first argument
1077
- * @return {Promise} A promise that resolves with the data when the operation
1078
- * completes successfully or rejects with the error after
1079
- * one occurs.
1080
- *
1081
- * @example
1082
- * <div>
1083
- * <code>
1084
- * // Examples use USGS Earthquake API:
1085
- * // https://earthquake.usgs.gov/fdsnws/event/1/#methods
1086
- *
1087
- * // displays an animation of all USGS earthquakes
1088
- * let earthquakes;
1089
- * let eqFeatureIndex = 0;
1090
- *
1091
- * function setup() {
1092
- * let url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson';
1093
- * httpDo(
1094
- * url,
1095
- * {
1096
- * method: 'GET',
1097
- * // Other Request options, like special headers for apis
1098
- * headers: { authorization: 'Bearer secretKey' }
1099
- * },
1100
- * function(res) {
1101
- * earthquakes = res;
1102
- * }
1103
- * );
1104
- * }
1105
- *
1106
- * function draw() {
1107
- * // wait until the data is loaded
1108
- * if (!earthquakes || !earthquakes.features[eqFeatureIndex]) {
1109
- * return;
1110
- * }
1111
- * clear();
1112
- *
1113
- * let feature = earthquakes.features[eqFeatureIndex];
1114
- * let mag = feature.properties.mag;
1115
- * let rad = mag / 11 * ((width + height) / 2);
1116
- * fill(255, 0, 0, 100);
1117
- * ellipse(width / 2 + random(-2, 2), height / 2 + random(-2, 2), rad, rad);
1118
- *
1119
- * if (eqFeatureIndex >= earthquakes.features.length) {
1120
- * eqFeatureIndex = 0;
1121
- * } else {
1122
- * eqFeatureIndex += 1;
1123
- * }
1124
- * }
1125
- * </code>
1126
- * </div>
1127
- */
1128
- /**
1129
- * @method httpDo
1130
- * @param {String|Request} path
1131
- * @param {Function} [callback]
1132
- * @param {Function} [errorCallback]
1133
- * @return {Promise}
1134
- */
1135
- fn.httpDo = async function (path, method, datatype, successCallback, errorCallback) {
1136
- // This behave similarly to httpGet but even more primitive. The user
1137
- // will most likely want to pass in a Request to path, the only convenience
1138
- // is that datatype will be taken into account to parse the response.
1139
-
1140
- if(typeof datatype === 'function'){
1141
- errorCallback = successCallback;
1142
- successCallback = datatype;
1143
- datatype = undefined;
1144
- }
1145
-
1146
- // Try to infer data type if it is defined
1147
- if(!datatype){
1148
- const extension = typeof path === 'string' ?
1149
- path.split(".").pop() :
1150
- path.url.split(".").pop();
1151
- switch(extension) {
1152
- case 'json':
1153
- datatype = 'json';
1154
- break;
1155
-
1156
- case 'jpg':
1157
- case 'jpeg':
1158
- case 'png':
1159
- case 'webp':
1160
- case 'gif':
1161
- datatype = 'blob';
1162
- break;
1163
-
1164
- case 'xml':
1165
- // NOTE: still need to normalize type handling/mapping
1166
- // datatype = 'xml';
1167
- case 'txt':
1168
- default:
1169
- datatype = 'text';
1170
- }
1171
- }
1172
-
1173
- const req = new Request(path, {
1174
- method
1175
- });
1176
-
1177
- try{
1178
- const { data } = await request(req, datatype);
1179
- if (successCallback) {
1180
- return successCallback(data);
1181
- } else {
1182
- return data;
1183
- }
1184
- } catch(err) {
1185
- if(errorCallback) {
1186
- return errorCallback(err);
1187
- } else {
1188
- throw err;
1189
- }
1190
- }
1191
- };
1192
-
1193
- /**
1194
- * @module IO
1195
- * @submodule Output
1196
- * @for p5
1197
- */
1198
- // private array of p5.PrintWriter objects
1199
- fn._pWriters = [];
1200
-
1201
- /**
1202
- * Creates a new <a href="#/p5.PrintWriter">p5.PrintWriter</a> object.
1203
- *
1204
- * <a href="#/p5.PrintWriter">p5.PrintWriter</a> objects provide a way to
1205
- * save a sequence of text data, called the *print stream*, to the user's
1206
- * computer. They're low-level objects that enable precise control of text
1207
- * output. Functions such as
1208
- * <a href="#/p5/saveStrings">saveStrings()</a> and
1209
- * <a href="#/p5/saveJSON">saveJSON()</a> are easier to use for simple file
1210
- * saving.
1211
- *
1212
- * The first parameter, `filename`, is the name of the file to be written. If
1213
- * a string is passed, as in `createWriter('words.txt')`, a new
1214
- * <a href="#/p5.PrintWriter">p5.PrintWriter</a> object will be created that
1215
- * writes to a file named `words.txt`.
1216
- *
1217
- * The second parameter, `extension`, is optional. If a string is passed, as
1218
- * in `createWriter('words', 'csv')`, the first parameter will be interpreted
1219
- * as the file name and the second parameter as the extension.
1220
- *
1221
- * @method createWriter
1222
- * @param {String} name name of the file to create.
1223
- * @param {String} [extension] format to use for the file.
1224
- * @return {p5.PrintWriter} stream for writing data.
1225
- *
1226
- * @example
1227
- * <div>
1228
- * <code>
1229
- * function setup() {
1230
- * createCanvas(100, 100);
1231
- *
1232
- * background(200);
1233
- *
1234
- * // Style the text.
1235
- * textAlign(LEFT, CENTER);
1236
- * textFont('Courier New');
1237
- * textSize(12);
1238
- *
1239
- * // Display instructions.
1240
- * text('Double-click to save', 5, 50, 90);
1241
- *
1242
- * describe('The text "Double-click to save" written in black on a gray background.');
1243
- * }
1244
- *
1245
- * // Save the file when the user double-clicks.
1246
- * function doubleClicked() {
1247
- * if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {
1248
- * // Create a p5.PrintWriter object.
1249
- * let myWriter = createWriter('xo.txt');
1250
- *
1251
- * // Add some lines to the print stream.
1252
- * myWriter.print('XOO');
1253
- * myWriter.print('OXO');
1254
- * myWriter.print('OOX');
1255
- *
1256
- * // Save the file and close the print stream.
1257
- * myWriter.close();
1258
- * }
1259
- * }
1260
- * </code>
1261
- * </div>
1262
- *
1263
- * <div>
1264
- * <code>
1265
- * function setup() {
1266
- * createCanvas(100, 100);
1267
- *
1268
- * background(200);
1269
- *
1270
- * // Style the text.
1271
- * textAlign(LEFT, CENTER);
1272
- * textFont('Courier New');
1273
- * textSize(12);
1274
- *
1275
- * // Display instructions.
1276
- * text('Double-click to save', 5, 50, 90);
1277
- *
1278
- * describe('The text "Double-click to save" written in black on a gray background.');
1279
- * }
1280
- *
1281
- * // Save the file when the user double-clicks.
1282
- * function doubleClicked() {
1283
- * if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {
1284
- * // Create a p5.PrintWriter object.
1285
- * // Use the file format .csv.
1286
- * let myWriter = createWriter('mauna_loa_co2', 'csv');
1287
- *
1288
- * // Add some lines to the print stream.
1289
- * myWriter.print('date,ppm_co2');
1290
- * myWriter.print('1960-01-01,316.43');
1291
- * myWriter.print('1970-01-01,325.06');
1292
- * myWriter.print('1980-01-01,337.9');
1293
- * myWriter.print('1990-01-01,353.86');
1294
- * myWriter.print('2000-01-01,369.45');
1295
- * myWriter.print('2020-01-01,413.61');
1296
- *
1297
- * // Save the file and close the print stream.
1298
- * myWriter.close();
1299
- * }
1300
- * }
1301
- * </code>
1302
- * </div>
1303
- */
1304
- fn.createWriter = function (name, extension) {
1305
- let newPW;
1306
- // check that it doesn't already exist
1307
- for (const i in fn._pWriters) {
1308
- if (fn._pWriters[i].name === name) {
1309
- // if a p5.PrintWriter w/ this name already exists...
1310
- // return fn._pWriters[i]; // return it w/ contents intact.
1311
- // or, could return a new, empty one with a unique name:
1312
- newPW = new p5.PrintWriter(name + this.millis(), extension);
1313
- fn._pWriters.push(newPW);
1314
- return newPW;
1315
- }
1316
- }
1317
- newPW = new p5.PrintWriter(name, extension);
1318
- fn._pWriters.push(newPW);
1319
- return newPW;
1320
- };
1321
-
1322
- /**
1323
- * A class to describe a print stream.
1324
- *
1325
- * Each `p5.PrintWriter` object provides a way to save a sequence of text
1326
- * data, called the *print stream*, to the user's computer. It's a low-level
1327
- * object that enables precise control of text output. Functions such as
1328
- * <a href="#/p5/saveStrings">saveStrings()</a> and
1329
- * <a href="#/p5/saveJSON">saveJSON()</a> are easier to use for simple file
1330
- * saving.
1331
- *
1332
- * Note: <a href="#/p5/createWriter">createWriter()</a> is the recommended way
1333
- * to make an instance of this class.
1334
- *
1335
- * @class p5.PrintWriter
1336
- * @param {String} filename name of the file to create.
1337
- * @param {String} [extension] format to use for the file.
1338
- *
1339
- * @example
1340
- * <div>
1341
- * <code>
1342
- * function setup() {
1343
- * createCanvas(100, 100);
1344
- *
1345
- * background(200);
1346
- *
1347
- * // Style the text.
1348
- * textAlign(LEFT, CENTER);
1349
- * textFont('Courier New');
1350
- * textSize(12);
1351
- *
1352
- * // Display instructions.
1353
- * text('Double-click to save', 5, 50, 90);
1354
- *
1355
- * describe('The text "Double-click to save" written in black on a gray background.');
1356
- * }
1357
- *
1358
- * // Save the file when the user double-clicks.
1359
- * function doubleClicked() {
1360
- * // Create a p5.PrintWriter object.
1361
- * let myWriter = createWriter('xo.txt');
1362
- *
1363
- * // Add some lines to the print stream.
1364
- * myWriter.print('XOO');
1365
- * myWriter.print('OXO');
1366
- * myWriter.print('OOX');
1367
- *
1368
- * // Save the file and close the print stream.
1369
- * myWriter.close();
1370
- * }
1371
- * </code>
1372
- * </div>
1373
- */
1374
- p5.PrintWriter = function (filename, extension) {
1375
- let self = this;
1376
- this.name = filename;
1377
- this.content = '';
1378
-
1379
- /**
1380
- * Writes data to the print stream without adding new lines.
1381
- *
1382
- * The parameter, `data`, is the data to write. `data` can be a number or
1383
- * string, as in `myWriter.write('hi')`, or an array of numbers and strings,
1384
- * as in `myWriter.write([1, 2, 3])`. A comma will be inserted between array
1385
- * array elements when they're added to the print stream.
1386
- *
1387
- * @method write
1388
- * @param {String|Number|Array} data data to be written as a string, number,
1389
- * or array of strings and numbers.
1390
- *
1391
- * @example
1392
- * <div>
1393
- * <code>
1394
- * function setup() {
1395
- * createCanvas(100, 100);
1396
- *
1397
- * background(200);
1398
- *
1399
- * // Style the text.
1400
- * textAlign(LEFT, CENTER);
1401
- * textFont('Courier New');
1402
- * textSize(12);
1403
- *
1404
- * // Display instructions.
1405
- * text('Double-click to save', 5, 50, 90);
1406
- *
1407
- * describe('The text "Double-click to save" written in black on a gray background.');
1408
- * }
1409
- *
1410
- * // Save the file when the user double-clicks.
1411
- * function doubleClicked() {
1412
- * // Create a p5.PrintWriter object.
1413
- * let myWriter = createWriter('numbers.txt');
1414
- *
1415
- * // Add some data to the print stream.
1416
- * myWriter.write('1,2,3,');
1417
- * myWriter.write(['4', '5', '6']);
1418
- *
1419
- * // Save the file and close the print stream.
1420
- * myWriter.close();
1421
- * }
1422
- * </code>
1423
- * </div>
1424
- */
1425
- this.write = function (data) {
1426
- this.content += data;
1427
- };
1428
-
1429
- /**
1430
- * Writes data to the print stream with new lines added.
1431
- *
1432
- * The parameter, `data`, is the data to write. `data` can be a number or
1433
- * string, as in `myWriter.print('hi')`, or an array of numbers and strings,
1434
- * as in `myWriter.print([1, 2, 3])`. A comma will be inserted between array
1435
- * array elements when they're added to the print stream.
1436
- *
1437
- * @method print
1438
- * @param {String|Number|Array} data data to be written as a string, number,
1439
- * or array of strings and numbers.
1440
- *
1441
- * @example
1442
- * <div>
1443
- * <code>
1444
- * function setup() {
1445
- * createCanvas(100, 100);
1446
- *
1447
- * background(200);
1448
- *
1449
- * // Style the text.
1450
- * textAlign(LEFT, CENTER);
1451
- * textFont('Courier New');
1452
- * textSize(12);
1453
- *
1454
- * // Display instructions.
1455
- * text('Double-click to save', 5, 50, 90);
1456
- *
1457
- * describe('The text "Double-click to save" written in black on a gray background.');
1458
- * }
1459
- *
1460
- * // Save the file when the user double-clicks.
1461
- * function doubleClicked() {
1462
- * // Create a p5.PrintWriter object.
1463
- * let myWriter = createWriter('numbers.txt');
1464
- *
1465
- * // Add some data to the print stream.
1466
- * myWriter.print('1,2,3,');
1467
- * myWriter.print(['4', '5', '6']);
1468
- *
1469
- * // Save the file and close the print stream.
1470
- * myWriter.close();
1471
- * }
1472
- * </code>
1473
- * </div>
1474
- */
1475
- this.print = function (data) {
1476
- this.content += `${data}\n`;
1477
- };
1478
-
1479
- /**
1480
- * Clears all data from the print stream.
1481
- *
1482
- * @method clear
1483
- *
1484
- * @example
1485
- * <div>
1486
- * <code>
1487
- * function setup() {
1488
- * createCanvas(100, 100);
1489
- *
1490
- * background(200);
1491
- *
1492
- * // Style the text.
1493
- * textAlign(LEFT, CENTER);
1494
- * textFont('Courier New');
1495
- * textSize(12);
1496
- *
1497
- * // Display instructions.
1498
- * text('Double-click to save', 5, 50, 90);
1499
- *
1500
- * describe('The text "Double-click to save" written in black on a gray background.');
1501
- * }
1502
- *
1503
- * // Save the file when the user double-clicks.
1504
- * function doubleClicked() {
1505
- * // Create a p5.PrintWriter object.
1506
- * let myWriter = createWriter('numbers.txt');
1507
- *
1508
- * // Add some data to the print stream.
1509
- * myWriter.print('Hello p5*js!');
1510
- *
1511
- * // Clear the print stream.
1512
- * myWriter.clear();
1513
- *
1514
- * // Save the file and close the print stream.
1515
- * myWriter.close();
1516
- * }
1517
- * </code>
1518
- * </div>
1519
- */
1520
- this.clear = function () {
1521
- this.content = '';
1522
- };
1523
-
1524
- /**
1525
- * Saves the file and closes the print stream.
1526
- *
1527
- * @method close
1528
- *
1529
- * @example
1530
- * <div>
1531
- * <code>
1532
- * function setup() {
1533
- * createCanvas(100, 100);
1534
- *
1535
- * background(200);
1536
- *
1537
- * // Style the text.
1538
- * textAlign(LEFT, CENTER);
1539
- * textFont('Courier New');
1540
- * textSize(12);
1541
- *
1542
- * // Display instructions.
1543
- * text('Double-click to save', 5, 50, 90);
1544
- *
1545
- * describe('The text "Double-click to save" written in black on a gray background.');
1546
- * }
1547
- *
1548
- * // Save the file when the user double-clicks.
1549
- * function doubleClicked() {
1550
- * // Create a p5.PrintWriter object.
1551
- * let myWriter = createWriter('cat.txt');
1552
- *
1553
- * // Add some data to the print stream.
1554
- * // ASCII art courtesy Wikipedia:
1555
- * // https://en.wikipedia.org/wiki/ASCII_art
1556
- * myWriter.print(' (\\_/) ');
1557
- * myWriter.print("(='.'=)");
1558
- * myWriter.print('(")_(")');
1559
- *
1560
- * // Save the file and close the print stream.
1561
- * myWriter.close();
1562
- * }
1563
- * </code>
1564
- * </div>
1565
- */
1566
- this.close = function () {
1567
- // convert String to Array for the writeFile Blob
1568
- const arr = [];
1569
- arr.push(this.content);
1570
- fn.writeFile(arr, filename, extension);
1571
- // remove from _pWriters array and delete self
1572
- for (const i in fn._pWriters) {
1573
- if (fn._pWriters[i].name === this.name) {
1574
- // remove from _pWriters array
1575
- fn._pWriters.splice(i, 1);
1576
- }
1577
- }
1578
- self.clear();
1579
- self = {};
1580
- };
1581
- };
1582
-
1583
- /**
1584
- * @module IO
1585
- * @submodule Output
1586
- * @for p5
1587
- */
1588
-
1589
- // object, filename, options --> saveJSON, saveStrings,
1590
- // filename, [extension] [canvas] --> saveImage
1591
-
1592
- /**
1593
- * Saves a given element(image, text, json, csv, wav, or html) to the client's
1594
- * computer. The first parameter can be a pointer to element we want to save.
1595
- * The element can be one of <a href="#/p5.Element">p5.Element</a>,an Array of
1596
- * Strings, an Array of JSON, a JSON object, a <a href="#/p5.Table">p5.Table
1597
- * </a>, a <a href="#/p5.Image">p5.Image</a>, or a p5.SoundFile (requires
1598
- * p5.sound). The second parameter is a filename (including extension).The
1599
- * third parameter is for options specific to this type of object. This method
1600
- * will save a file that fits the given parameters.
1601
- * If it is called without specifying an element, by default it will save the
1602
- * whole canvas as an image file. You can optionally specify a filename as
1603
- * the first parameter in such a case.
1604
- * **Note that it is not recommended to
1605
- * call this method within draw, as it will open a new save dialog on every
1606
- * render.**
1607
- *
1608
- * @method save
1609
- * @param {Object|String} [objectOrFilename] If filename is provided, will
1610
- * save canvas as an image with
1611
- * either png or jpg extension
1612
- * depending on the filename.
1613
- * If object is provided, will
1614
- * save depending on the object
1615
- * and filename (see examples
1616
- * above).
1617
- * @param {String} [filename] If an object is provided as the first
1618
- * parameter, then the second parameter
1619
- * indicates the filename,
1620
- * and should include an appropriate
1621
- * file extension (see examples above).
1622
- * @param {Boolean|String} [options] Additional options depend on
1623
- * filetype. For example, when saving JSON,
1624
- * <code>true</code> indicates that the
1625
- * output will be optimized for filesize,
1626
- * rather than readability.
1627
- *
1628
- * @example
1629
- * <div class="norender"><code>
1630
- * // Saves the canvas as an image
1631
- * cnv = createCanvas(300, 300);
1632
- * save(cnv, 'myCanvas.jpg');
1633
- *
1634
- * // Saves the canvas as an image by default
1635
- * save('myCanvas.jpg');
1636
- * describe('An example for saving a canvas as an image.');
1637
- * </code></div>
1638
- *
1639
- * <div class="norender"><code>
1640
- * // Saves p5.Image as an image
1641
- * img = createImage(10, 10);
1642
- * save(img, 'myImage.png');
1643
- * describe('An example for saving a p5.Image element as an image.');
1644
- * </code></div>
1645
- *
1646
- * <div class="norender"><code>
1647
- * // Saves p5.Renderer object as an image
1648
- * obj = createGraphics(100, 100);
1649
- * save(obj, 'myObject.png');
1650
- * describe('An example for saving a p5.Renderer element.');
1651
- * </code></div>
1652
- *
1653
- * <div class="norender"><code>
1654
- * let myTable = new p5.Table();
1655
- * // Saves table as html file
1656
- * save(myTable, 'myTable.html');
1657
- *
1658
- * // Comma Separated Values
1659
- * save(myTable, 'myTable.csv');
1660
- *
1661
- * // Tab Separated Values
1662
- * save(myTable, 'myTable.tsv');
1663
- *
1664
- * describe(`An example showing how to save a table in formats of
1665
- * HTML, CSV and TSV.`);
1666
- * </code></div>
1667
- *
1668
- * <div class="norender"><code>
1669
- * let myJSON = { a: 1, b: true };
1670
- *
1671
- * // Saves pretty JSON
1672
- * save(myJSON, 'my.json');
1673
- *
1674
- * // Optimizes JSON filesize
1675
- * save(myJSON, 'my.json', true);
1676
- *
1677
- * describe('An example for saving JSON to a txt file with some extra arguments.');
1678
- * </code></div>
1679
- *
1680
- * <div class="norender"><code>
1681
- * // Saves array of strings to text file with line breaks after each item
1682
- * let arrayOfStrings = ['a', 'b'];
1683
- * save(arrayOfStrings, 'my.txt');
1684
- * describe(`An example for saving an array of strings to text file
1685
- * with line breaks.`);
1686
- * </code></div>
1687
- */
1688
- fn.save = function (object, _filename, _options) {
1689
- // TODO: parameters is not used correctly
1690
- // parse the arguments and figure out which things we are saving
1691
- const args = arguments;
1692
- // =================================================
1693
- // OPTION 1: saveCanvas...
1694
-
1695
- // if no arguments are provided, save canvas
1696
- const cnv = this._curElement ? this._curElement.elt : this.elt;
1697
- if (args.length === 0) {
1698
- fn.saveCanvas(cnv);
1699
- return;
1700
-
1701
- } else if (args[0] instanceof Renderer || args[0] instanceof Graphics) {
1702
- // otherwise, parse the arguments
1703
- // if first param is a p5Graphics, then saveCanvas
1704
- fn.saveCanvas(args[0].canvas, args[1], args[2]);
1705
- return;
1706
-
1707
- } else if (args.length === 1 && typeof args[0] === 'string') {
1708
- // if 1st param is String and only one arg, assume it is canvas filename
1709
- fn.saveCanvas(cnv, args[0]);
1710
-
1711
- } else {
1712
- // =================================================
1713
- // OPTION 2: extension clarifies saveStrings vs. saveJSON
1714
- const extension = _checkFileExtension(args[1], args[2])[1];
1715
- switch (extension) {
1716
- case 'json':
1717
- fn.saveJSON(args[0], args[1], args[2]);
1718
- return;
1719
- case 'txt':
1720
- fn.saveStrings(args[0], args[1], args[2]);
1721
- return;
1722
- // =================================================
1723
- // OPTION 3: decide based on object...
1724
- default:
1725
- if (args[0] instanceof Array) {
1726
- fn.saveStrings(args[0], args[1], args[2]);
1727
- } else if (args[0] instanceof p5.Table) {
1728
- fn.saveTable(args[0], args[1], args[2]);
1729
- } else if (args[0] instanceof p5.Image) {
1730
- fn.saveCanvas(args[0].canvas, args[1]);
1731
- } else if (args[0] instanceof p5.SoundFile) {
1732
- fn.saveSound(args[0], args[1], args[2], args[3]);
1733
- }
1734
- }
1735
- }
1736
- };
1737
-
1738
- /**
1739
- * Saves an `Object` or `Array` to a JSON file.
1740
- *
1741
- * JavaScript Object Notation
1742
- * (<a href="https://developer.mozilla.org/en-US/docs/Glossary/JSON" target="_blank">JSON</a>)
1743
- * is a standard format for sending data between applications. The format is
1744
- * based on JavaScript objects which have keys and values. JSON files store
1745
- * data in an object with strings as keys. Values can be strings, numbers,
1746
- * Booleans, arrays, `null`, or other objects.
1747
- *
1748
- * The first parameter, `json`, is the data to save. The data can be an array,
1749
- * as in `[1, 2, 3]`, or an object, as in
1750
- * `{ x: 50, y: 50, color: 'deeppink' }`.
1751
- *
1752
- * The second parameter, `filename`, is a string that sets the file's name.
1753
- * For example, calling `saveJSON([1, 2, 3], 'data.json')` saves the array
1754
- * `[1, 2, 3]` to a file called `data.json` on the user's computer.
1755
- *
1756
- * The third parameter, `optimize`, is optional. If `true` is passed, as in
1757
- * `saveJSON([1, 2, 3], 'data.json', true)`, then all unneeded whitespace will
1758
- * be removed to reduce the file size.
1759
- *
1760
- * Note: The browser will either save the file immediately or prompt the user
1761
- * with a dialogue window.
1762
- *
1763
- * @method saveJSON
1764
- * @param {Array|Object} json data to save.
1765
- * @param {String} filename name of the file to be saved.
1766
- * @param {Boolean} [optimize] whether to trim unneeded whitespace. Defaults
1767
- * to `true`.
1768
- *
1769
- * @example
1770
- * <div>
1771
- * <code>
1772
- * function setup() {
1773
- * createCanvas(100, 100);
1774
- *
1775
- * background(200);
1776
- *
1777
- * // Style the text.
1778
- * textAlign(LEFT, CENTER);
1779
- * textFont('Courier New');
1780
- * textSize(12);
1781
- *
1782
- * // Display instructions.
1783
- * text('Double-click to save', 5, 50, 90);
1784
- *
1785
- * describe('The text "Double-click to save" written in black on a gray background.');
1786
- * }
1787
- *
1788
- * // Save the file when the user double-clicks.
1789
- * function doubleClicked() {
1790
- * if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {
1791
- * // Create an array.
1792
- * let data = [1, 2, 3];
1793
- *
1794
- * // Save the JSON file.
1795
- * saveJSON(data, 'numbers.json');
1796
- * }
1797
- * }
1798
- * </code>
1799
- * </div>
1800
- *
1801
- * <div>
1802
- * <code>
1803
- * function setup() {
1804
- * createCanvas(100, 100);
1805
- *
1806
- * background(200);
1807
- *
1808
- * // Style the text.
1809
- * textAlign(LEFT, CENTER);
1810
- * textFont('Courier New');
1811
- * textSize(12);
1812
- *
1813
- * // Display instructions.
1814
- * text('Double-click to save', 5, 50, 90);
1815
- *
1816
- * describe('The text "Double-click to save" written in black on a gray background.');
1817
- * }
1818
- *
1819
- * // Save the file when the user double-clicks.
1820
- * function doubleClicked() {
1821
- * if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {
1822
- * // Create an object.
1823
- * let data = { x: mouseX, y: mouseY };
1824
- *
1825
- * // Save the JSON file.
1826
- * saveJSON(data, 'state.json');
1827
- * }
1828
- * }
1829
- * </code>
1830
- * </div>
1831
- *
1832
- * <div>
1833
- * <code>
1834
- * function setup() {
1835
- * createCanvas(100, 100);
1836
- *
1837
- * background(200);
1838
- *
1839
- * // Style the text.
1840
- * textAlign(LEFT, CENTER);
1841
- * textFont('Courier New');
1842
- * textSize(12);
1843
- *
1844
- * // Display instructions.
1845
- * text('Double-click to save', 5, 50, 90);
1846
- *
1847
- * describe('The text "Double-click to save" written in black on a gray background.');
1848
- * }
1849
- *
1850
- * // Save the file when the user double-clicks.
1851
- * function doubleClicked() {
1852
- * if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {
1853
- * // Create an object.
1854
- * let data = { x: mouseX, y: mouseY };
1855
- *
1856
- * // Save the JSON file and reduce its size.
1857
- * saveJSON(data, 'state.json', true);
1858
- * }
1859
- * }
1860
- * </code>
1861
- * </div>
1862
- */
1863
- fn.saveJSON = function (json, filename, optimize) {
1864
- // p5._validateParameters('saveJSON', arguments);
1865
- let stringify;
1866
- if (optimize) {
1867
- stringify = JSON.stringify(json);
1868
- } else {
1869
- stringify = JSON.stringify(json, undefined, 2);
1870
- }
1871
- this.saveStrings(stringify.split('\n'), filename, 'json');
1872
- };
1873
-
1874
- /**
1875
- * Saves an `Array` of `String`s to a file, one per line.
1876
- *
1877
- * The first parameter, `list`, is an array with the strings to save.
1878
- *
1879
- * The second parameter, `filename`, is a string that sets the file's name.
1880
- * For example, calling `saveStrings(['0', '01', '011'], 'data.txt')` saves
1881
- * the array `['0', '01', '011']` to a file called `data.txt` on the user's
1882
- * computer.
1883
- *
1884
- * The third parameter, `extension`, is optional. If a string is passed, as in
1885
- * `saveStrings(['0', '01', '0`1'], 'data', 'txt')`, the second parameter will
1886
- * be interpreted as the file name and the third parameter as the extension.
1887
- *
1888
- * The fourth parameter, `isCRLF`, is also optional, If `true` is passed, as
1889
- * in `saveStrings(['0', '01', '011'], 'data', 'txt', true)`, then two
1890
- * characters, `\r\n` , will be added to the end of each string to create new
1891
- * lines in the saved file. `\r` is a carriage return (CR) and `\n` is a line
1892
- * feed (LF). By default, only `\n` (line feed) is added to each string in
1893
- * order to create new lines.
1894
- *
1895
- * Note: The browser will either save the file immediately or prompt the user
1896
- * with a dialogue window.
1897
- *
1898
- * @method saveStrings
1899
- * @param {String[]} list data to save.
1900
- * @param {String} filename name of file to be saved.
1901
- * @param {String} [extension] format to use for the file.
1902
- * @param {Boolean} [isCRLF] whether to add `\r\n` to the end of each
1903
- * string. Defaults to `false`.
1904
- *
1905
- * @example
1906
- * <div>
1907
- * <code>
1908
- * function setup() {
1909
- * createCanvas(100, 100);
1910
- *
1911
- * background(200);
1912
- *
1913
- * // Style the text.
1914
- * textAlign(LEFT, CENTER);
1915
- * textFont('Courier New');
1916
- * textSize(12);
1917
- *
1918
- * // Display instructions.
1919
- * text('Double-click to save', 5, 50, 90);
1920
- *
1921
- * describe('The text "Double-click to save" written in black on a gray background.');
1922
- * }
1923
- *
1924
- * // Save the file when the user double-clicks.
1925
- * function doubleClicked() {
1926
- * if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {
1927
- * // Create an array.
1928
- * let data = ['0', '01', '011'];
1929
- *
1930
- * // Save the text file.
1931
- * saveStrings(data, 'data.txt');
1932
- * }
1933
- * }
1934
- * </code>
1935
- * </div>
1936
- *
1937
- * <div>
1938
- * <code>
1939
- * function setup() {
1940
- * createCanvas(100, 100);
1941
- *
1942
- * background(200);
1943
- *
1944
- * // Style the text.
1945
- * textAlign(LEFT, CENTER);
1946
- * textFont('Courier New');
1947
- * textSize(12);
1948
- *
1949
- * // Display instructions.
1950
- * text('Double-click to save', 5, 50, 90);
1951
- *
1952
- * describe('The text "Double-click to save" written in black on a gray background.');
1953
- * }
1954
- *
1955
- * // Save the file when the user double-clicks.
1956
- * function doubleClicked() {
1957
- * if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {
1958
- * // Create an array.
1959
- * // ASCII art courtesy Wikipedia:
1960
- * // https://en.wikipedia.org/wiki/ASCII_art
1961
- * let data = [' (\\_/) ', "(='.'=)", '(")_(")'];
1962
- *
1963
- * // Save the text file.
1964
- * saveStrings(data, 'cat', 'txt');
1965
- * }
1966
- * }
1967
- * </code>
1968
- * </div>
1969
- *
1970
- * <div>
1971
- * <code>
1972
- * function setup() {
1973
- * createCanvas(100, 100);
1974
- *
1975
- * background(200);
1976
- *
1977
- * // Style the text.
1978
- * textAlign(LEFT, CENTER);
1979
- * textFont('Courier New');
1980
- * textSize(12);
1981
- *
1982
- * // Display instructions.
1983
- * text('Double-click to save', 5, 50, 90);
1984
- *
1985
- * describe('The text "Double-click to save" written in black on a gray background.');
1986
- * }
1987
- *
1988
- * // Save the file when the user double-clicks.
1989
- * function doubleClicked() {
1990
- * if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {
1991
- * // Create an array.
1992
- * // +--+
1993
- * // / /|
1994
- * // +--+ +
1995
- * // | |/
1996
- * // +--+
1997
- * let data = [' +--+', ' / /|', '+--+ +', '| |/', '+--+'];
1998
- *
1999
- * // Save the text file.
2000
- * // Use CRLF for line endings.
2001
- * saveStrings(data, 'box', 'txt', true);
2002
- * }
2003
- * }
2004
- * </code>
2005
- * </div>
2006
- */
2007
- fn.saveStrings = function (list, filename, extension, isCRLF) {
2008
- // p5._validateParameters('saveStrings', arguments);
2009
- const ext = extension || 'txt';
2010
- const pWriter = new p5.PrintWriter(filename, ext);
2011
- for (let item of list) {
2012
- isCRLF ? pWriter.write(item + '\r\n') : pWriter.write(item + '\n');
2013
- }
2014
- pWriter.close();
2015
- pWriter.clear();
2016
- };
2017
-
2018
- // =======
2019
- // HELPERS
2020
- // =======
2021
-
2022
- function escapeHelper(content) {
2023
- return content
2024
- .replace(/&/g, '&amp;')
2025
- .replace(/</g, '&lt;')
2026
- .replace(/>/g, '&gt;')
2027
- .replace(/"/g, '&quot;')
2028
- .replace(/'/g, '&#039;');
2029
- }
2030
-
2031
- /**
2032
- * Writes the contents of a <a href="#/p5.Table">Table</a> object to a file. Defaults to a
2033
- * text file with comma-separated-values ('csv') but can also
2034
- * use tab separation ('tsv'), or generate an HTML table ('html').
2035
- * The file saving process and location of the saved file will
2036
- * vary between web browsers.
2037
- *
2038
- * @method saveTable
2039
- * @deprecated p5.Table will be removed in a future version of p5.js to make way for a new, friendlier version :)
2040
- * @param {p5.Table} Table the <a href="#/p5.Table">Table</a> object to save to a file
2041
- * @param {String} filename the filename to which the Table should be saved
2042
- * @param {String} [options] can be one of "tsv", "csv", or "html"
2043
- * @example
2044
- * <div><code>
2045
- * let table;
2046
- *
2047
- * function setup() {
2048
- * table = new p5.Table();
2049
- *
2050
- * table.addColumn('id');
2051
- * table.addColumn('species');
2052
- * table.addColumn('name');
2053
- *
2054
- * let newRow = table.addRow();
2055
- * newRow.setNum('id', table.getRowCount() - 1);
2056
- * newRow.setString('species', 'Panthera leo');
2057
- * newRow.setString('name', 'Lion');
2058
- *
2059
- * // To save, un-comment next line then click 'run'
2060
- * // saveTable(table, 'new.csv');
2061
- *
2062
- * describe('no image displayed');
2063
- * }
2064
- *
2065
- * // Saves the following to a file called 'new.csv':
2066
- * // id,species,name
2067
- * // 0,Panthera leo,Lion
2068
- * </code></div>
2069
- */
2070
- fn.saveTable = function (table, filename, options) {
2071
- // p5._validateParameters('saveTable', arguments);
2072
- let ext;
2073
- if (options === undefined) {
2074
- ext = filename.substring(filename.lastIndexOf('.') + 1, filename.length);
2075
- if(ext === filename) ext = 'csv';
2076
- } else {
2077
- ext = options;
2078
- }
2079
- const pWriter = this.createWriter(filename, ext);
2080
-
2081
- const header = table.columns;
2082
-
2083
- let sep = ','; // default to CSV
2084
- if (ext === 'tsv') {
2085
- sep = '\t';
2086
- }
2087
- if (ext !== 'html') {
2088
- const output = table.toString(sep);
2089
- pWriter.write(output);
2090
- } else {
2091
- // otherwise, make HTML
2092
- pWriter.print('<html>');
2093
- pWriter.print('<head>');
2094
- let str = ' <meta http-equiv="content-type" content';
2095
- str += '="text/html;charset=utf-8" />';
2096
- pWriter.print(str);
2097
- pWriter.print('</head>');
2098
-
2099
- pWriter.print('<body>');
2100
- pWriter.print(' <table>');
2101
-
2102
- // make header if it has values
2103
- if (header[0] !== '0') {
2104
- pWriter.print(' <tr>');
2105
- for (let k = 0; k < header.length; k++) {
2106
- const e = escapeHelper(header[k]);
2107
- pWriter.print(` <td>${e}`);
2108
- pWriter.print(' </td>');
2109
- }
2110
- pWriter.print(' </tr>');
2111
- }
2112
-
2113
- // make rows
2114
- for (let row = 0; row < table.rows.length; row++) {
2115
- pWriter.print(' <tr>');
2116
- for (let col = 0; col < table.columns.length; col++) {
2117
- const entry = table.rows[row].getString(col);
2118
- const htmlEntry = escapeHelper(entry);
2119
- pWriter.print(` <td>${htmlEntry}`);
2120
- pWriter.print(' </td>');
2121
- }
2122
- pWriter.print(' </tr>');
2123
- }
2124
- pWriter.print(' </table>');
2125
- pWriter.print('</body>');
2126
- pWriter.print('</html>');
2127
- }
2128
- // close and clear the pWriter
2129
- pWriter.close();
2130
- pWriter.clear();
2131
- }; // end saveTable()
2132
-
2133
- /**
2134
- * Generate a blob of file data as a url to prepare for download.
2135
- * Accepts an array of data, a filename, and an extension (optional).
2136
- * This is a private function because it does not do any formatting,
2137
- * but it is used by <a href="#/p5/saveStrings">saveStrings</a>, <a href="#/p5/saveJSON">saveJSON</a>, <a href="#/p5/saveTable">saveTable</a> etc.
2138
- *
2139
- * @param {Array} dataToDownload
2140
- * @param {String} filename
2141
- * @param {String} [extension]
2142
- * @private
2143
- */
2144
- fn.writeFile = function (dataToDownload, filename, extension) {
2145
- let type = 'application/octet-stream';
2146
- if (fn._isSafari()) {
2147
- type = 'text/plain';
2148
- }
2149
- const blob = new Blob(dataToDownload, {
2150
- type
2151
- });
2152
- fn.downloadFile(blob, filename, extension);
2153
- };
2154
-
2155
- /**
2156
- * Forces download. Accepts a url to filedata/blob, a filename,
2157
- * and an extension (optional).
2158
- * This is a private function because it does not do any formatting,
2159
- * but it is used by <a href="#/p5/saveStrings">saveStrings</a>, <a href="#/p5/saveJSON">saveJSON</a>, <a href="#/p5/saveTable">saveTable</a> etc.
2160
- *
2161
- * @method downloadFile
2162
- * @private
2163
- * @param {String|Blob} data either an href generated by createObjectURL,
2164
- * or a Blob object containing the data
2165
- * @param {String} [filename]
2166
- * @param {String} [extension]
2167
- */
2168
- fn.downloadFile = downloadFile;
2169
-
2170
- /**
2171
- * Returns a file extension, or another string
2172
- * if the provided parameter has no extension.
2173
- *
2174
- * @param {String} filename
2175
- * @param {String} [extension]
2176
- * @return {String[]} [fileName, fileExtension]
2177
- *
2178
- * @private
2179
- */
2180
- fn._checkFileExtension = _checkFileExtension;
2181
-
2182
- /**
2183
- * Returns true if the browser is Safari, false if not.
2184
- * Safari makes trouble for downloading files.
2185
- *
2186
- * @return {Boolean} [description]
2187
- * @private
2188
- */
2189
- fn._isSafari = function () {
2190
- // The following line is CC BY SA 3 by user Fregante https://stackoverflow.com/a/23522755
2191
- return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
2192
- };
2193
-
2194
- /**
2195
- * Helper function, a callback for download that deletes
2196
- * an invisible anchor element from the DOM once the file
2197
- * has been automatically downloaded.
2198
- *
2199
- * @private
2200
- */
2201
- function destroyClickedElement(event) {
2202
- document.body.removeChild(event.target);
2203
- }
2204
- }
2205
-
2206
- export default files;
2207
-
2208
- if(typeof p5 !== 'undefined'){
2209
- files(p5, p5.prototype);
2210
- }