jclic 2.1.21 → 2.1.23

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 (175) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/jclic-node.js +9 -8
  3. package/dist/jclic-node.js.map +1 -1
  4. package/dist/jclic.min.js +2 -2
  5. package/dist/jclic.min.js.map +1 -1
  6. package/package.json +4 -4
  7. package/src/GlobalData.js +1 -1
  8. package/src/JClicPlayer.js +2 -2
  9. package/src/bags/MediaBag.js +6 -5
  10. package/dist/1078.jclic-node.js +0 -282
  11. package/dist/1078.jclic-node.js.map +0 -1
  12. package/dist/1196.jclic-node.js +0 -808
  13. package/dist/1196.jclic-node.js.map +0 -1
  14. package/dist/1253.jclic-node.js +0 -1432
  15. package/dist/1253.jclic-node.js.map +0 -1
  16. package/dist/13.jclic-node.js +0 -103
  17. package/dist/13.jclic-node.js.map +0 -1
  18. package/dist/1567.jclic-node.js +0 -2313
  19. package/dist/1567.jclic-node.js.map +0 -1
  20. package/dist/1588.jclic-node.js +0 -602
  21. package/dist/1588.jclic-node.js.map +0 -1
  22. package/dist/1725.jclic-node.js +0 -836
  23. package/dist/1725.jclic-node.js.map +0 -1
  24. package/dist/1731.jclic-node.js +0 -438
  25. package/dist/1731.jclic-node.js.map +0 -1
  26. package/dist/1842.jclic-node.js +0 -651
  27. package/dist/1842.jclic-node.js.map +0 -1
  28. package/dist/2160.jclic-node.js +0 -1016
  29. package/dist/2160.jclic-node.js.map +0 -1
  30. package/dist/222.jclic-node.js +0 -129
  31. package/dist/222.jclic-node.js.map +0 -1
  32. package/dist/2316.jclic-node.js +0 -949
  33. package/dist/2316.jclic-node.js.map +0 -1
  34. package/dist/2355.jclic-node.js +0 -371
  35. package/dist/2355.jclic-node.js.map +0 -1
  36. package/dist/2366.jclic-node.js +0 -431
  37. package/dist/2366.jclic-node.js.map +0 -1
  38. package/dist/2379.jclic-node.js +0 -202
  39. package/dist/2379.jclic-node.js.map +0 -1
  40. package/dist/2437.jclic-node.js +0 -450
  41. package/dist/2437.jclic-node.js.map +0 -1
  42. package/dist/2531.jclic-node.js +0 -869
  43. package/dist/2531.jclic-node.js.map +0 -1
  44. package/dist/2608.jclic-node.js +0 -160
  45. package/dist/2608.jclic-node.js.map +0 -1
  46. package/dist/2715.jclic-node.js +0 -554
  47. package/dist/2715.jclic-node.js.map +0 -1
  48. package/dist/277.jclic-node.js +0 -22
  49. package/dist/277.jclic-node.js.map +0 -1
  50. package/dist/2921.jclic-node.js +0 -660
  51. package/dist/2921.jclic-node.js.map +0 -1
  52. package/dist/2952.jclic-node.js +0 -101
  53. package/dist/2952.jclic-node.js.map +0 -1
  54. package/dist/3018.jclic-node.js +0 -421
  55. package/dist/3018.jclic-node.js.map +0 -1
  56. package/dist/3019.jclic-node.js +0 -682
  57. package/dist/3019.jclic-node.js.map +0 -1
  58. package/dist/3231.jclic-node.js +0 -274
  59. package/dist/3231.jclic-node.js.map +0 -1
  60. package/dist/331.jclic-node.js +0 -115
  61. package/dist/331.jclic-node.js.map +0 -1
  62. package/dist/3391.jclic-node.js +0 -276
  63. package/dist/3391.jclic-node.js.map +0 -1
  64. package/dist/3502.jclic-node.js +0 -671
  65. package/dist/3502.jclic-node.js.map +0 -1
  66. package/dist/3653.jclic-node.js +0 -982
  67. package/dist/3653.jclic-node.js.map +0 -1
  68. package/dist/371.jclic.min.js +0 -2
  69. package/dist/371.jclic.min.js.map +0 -1
  70. package/dist/3856.jclic-node.js +0 -575
  71. package/dist/3856.jclic-node.js.map +0 -1
  72. package/dist/4112.jclic-node.js +0 -659
  73. package/dist/4112.jclic-node.js.map +0 -1
  74. package/dist/4123.jclic-node.js +0 -910
  75. package/dist/4123.jclic-node.js.map +0 -1
  76. package/dist/427.jclic-node.js +0 -894
  77. package/dist/427.jclic-node.js.map +0 -1
  78. package/dist/4483.jclic-node.js +0 -327
  79. package/dist/4483.jclic-node.js.map +0 -1
  80. package/dist/4548.jclic-node.js +0 -1078
  81. package/dist/4548.jclic-node.js.map +0 -1
  82. package/dist/466.jclic-node.js +0 -99
  83. package/dist/466.jclic-node.js.map +0 -1
  84. package/dist/485.jclic-node.js +0 -783
  85. package/dist/485.jclic-node.js.map +0 -1
  86. package/dist/4921.jclic-node.js +0 -500
  87. package/dist/4921.jclic-node.js.map +0 -1
  88. package/dist/5091.jclic-node.js +0 -239
  89. package/dist/5091.jclic-node.js.map +0 -1
  90. package/dist/520.jclic-node.js +0 -550
  91. package/dist/520.jclic-node.js.map +0 -1
  92. package/dist/5312.jclic-node.js +0 -1126
  93. package/dist/5312.jclic-node.js.map +0 -1
  94. package/dist/5338.jclic-node.js +0 -212
  95. package/dist/5338.jclic-node.js.map +0 -1
  96. package/dist/5344.jclic-node.js +0 -229
  97. package/dist/5344.jclic-node.js.map +0 -1
  98. package/dist/5550.jclic-node.js +0 -238
  99. package/dist/5550.jclic-node.js.map +0 -1
  100. package/dist/5626.jclic-node.js +0 -614
  101. package/dist/5626.jclic-node.js.map +0 -1
  102. package/dist/5977.jclic-node.js +0 -1081
  103. package/dist/5977.jclic-node.js.map +0 -1
  104. package/dist/6148.jclic-node.js +0 -345
  105. package/dist/6148.jclic-node.js.map +0 -1
  106. package/dist/6176.jclic-node.js +0 -481
  107. package/dist/6176.jclic-node.js.map +0 -1
  108. package/dist/6221.jclic-node.js +0 -1072
  109. package/dist/6221.jclic-node.js.map +0 -1
  110. package/dist/6238.jclic-node.js +0 -718
  111. package/dist/6238.jclic-node.js.map +0 -1
  112. package/dist/6454.jclic-node.js +0 -1413
  113. package/dist/6454.jclic-node.js.map +0 -1
  114. package/dist/6565.jclic-node.js +0 -294
  115. package/dist/6565.jclic-node.js.map +0 -1
  116. package/dist/6579.jclic-node.js +0 -719
  117. package/dist/6579.jclic-node.js.map +0 -1
  118. package/dist/6715.jclic-node.js +0 -148
  119. package/dist/6715.jclic-node.js.map +0 -1
  120. package/dist/6777.jclic-node.js +0 -171
  121. package/dist/6777.jclic-node.js.map +0 -1
  122. package/dist/6782.jclic-node.js +0 -1611
  123. package/dist/6782.jclic-node.js.map +0 -1
  124. package/dist/6847.jclic-node.js +0 -601
  125. package/dist/6847.jclic-node.js.map +0 -1
  126. package/dist/6856.jclic-node.js +0 -252
  127. package/dist/6856.jclic-node.js.map +0 -1
  128. package/dist/696.jclic-node.js +0 -1821
  129. package/dist/696.jclic-node.js.map +0 -1
  130. package/dist/698.jclic-node.js +0 -583
  131. package/dist/698.jclic-node.js.map +0 -1
  132. package/dist/704.jclic-node.js +0 -80
  133. package/dist/704.jclic-node.js.map +0 -1
  134. package/dist/7046.jclic-node.js +0 -735
  135. package/dist/7046.jclic-node.js.map +0 -1
  136. package/dist/7220.jclic-node.js +0 -156
  137. package/dist/7220.jclic-node.js.map +0 -1
  138. package/dist/7257.jclic-node.js +0 -931
  139. package/dist/7257.jclic-node.js.map +0 -1
  140. package/dist/743.jclic-node.js +0 -583
  141. package/dist/743.jclic-node.js.map +0 -1
  142. package/dist/757.jclic-node.js +0 -1072
  143. package/dist/757.jclic-node.js.map +0 -1
  144. package/dist/7781.jclic-node.js +0 -202
  145. package/dist/7781.jclic-node.js.map +0 -1
  146. package/dist/7912.jclic-node.js +0 -2103
  147. package/dist/7912.jclic-node.js.map +0 -1
  148. package/dist/827.jclic-node.js +0 -708
  149. package/dist/827.jclic-node.js.map +0 -1
  150. package/dist/8276.jclic-node.js +0 -409
  151. package/dist/8276.jclic-node.js.map +0 -1
  152. package/dist/8322.jclic-node.js +0 -498
  153. package/dist/8322.jclic-node.js.map +0 -1
  154. package/dist/8641.jclic-node.js +0 -360
  155. package/dist/8641.jclic-node.js.map +0 -1
  156. package/dist/8837.jclic-node.js +0 -651
  157. package/dist/8837.jclic-node.js.map +0 -1
  158. package/dist/8895.jclic-node.js +0 -151
  159. package/dist/8895.jclic-node.js.map +0 -1
  160. package/dist/9072.jclic-node.js +0 -1285
  161. package/dist/9072.jclic-node.js.map +0 -1
  162. package/dist/9078.jclic-node.js +0 -935
  163. package/dist/9078.jclic-node.js.map +0 -1
  164. package/dist/9103.jclic-node.js +0 -718
  165. package/dist/9103.jclic-node.js.map +0 -1
  166. package/dist/9359.jclic-node.js +0 -145
  167. package/dist/9359.jclic-node.js.map +0 -1
  168. package/dist/9409.jclic-node.js +0 -921
  169. package/dist/9409.jclic-node.js.map +0 -1
  170. package/dist/9513.jclic-node.js +0 -720
  171. package/dist/9513.jclic-node.js.map +0 -1
  172. package/dist/9704.jclic-node.js +0 -81
  173. package/dist/9704.jclic-node.js.map +0 -1
  174. package/dist/9950.jclic-node.js +0 -827
  175. package/dist/9950.jclic-node.js.map +0 -1
@@ -1,2103 +0,0 @@
1
- "use strict";
2
- exports.id = 7912;
3
- exports.ids = [7912];
4
- exports.modules = {
5
-
6
- /***/ 7912:
7
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
8
-
9
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
10
- /* harmony export */ Hf: () => (/* binding */ Gradient),
11
- /* harmony export */ KQ: () => (/* binding */ Font),
12
- /* harmony export */ M4: () => (/* binding */ Timer),
13
- /* harmony export */ M_: () => (/* binding */ Rectangle),
14
- /* harmony export */ Pp: () => (/* binding */ Ellipse),
15
- /* harmony export */ bR: () => (/* binding */ Point),
16
- /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__),
17
- /* harmony export */ fg: () => (/* binding */ Dimension),
18
- /* harmony export */ kg: () => (/* binding */ PathStroke),
19
- /* harmony export */ mc: () => (/* binding */ Container),
20
- /* harmony export */ rc: () => (/* binding */ Action),
21
- /* harmony export */ tc: () => (/* binding */ Stroke),
22
- /* harmony export */ wA: () => (/* binding */ Path),
23
- /* harmony export */ yp: () => (/* binding */ Shape)
24
- /* harmony export */ });
25
- /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7750);
26
- /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);
27
- /* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1253);
28
- /* harmony import */ var webfontloader__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4356);
29
- /* harmony import */ var webfontloader__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(webfontloader__WEBPACK_IMPORTED_MODULE_2__);
30
- /**
31
- * File : AWT.js
32
- * Created : 12/04/2015
33
- * By : Francesc Busquets <francesc@gmail.com>
34
- *
35
- * JClic.js
36
- * An HTML5 player of JClic activities
37
- * https://projectestac.github.io/jclic.js
38
- *
39
- * @source https://github.com/projectestac/jclic.js
40
- *
41
- * @license EUPL-1.2
42
- * @licstart
43
- * (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)
44
- *
45
- * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by
46
- * the European Commission- subsequent versions of the EUPL (the "Licence");
47
- * You may not use this work except in compliance with the Licence.
48
- *
49
- * You may obtain a copy of the Licence at:
50
- * https://joinup.ec.europa.eu/software/page/eupl
51
- *
52
- * Unless required by applicable law or agreed to in writing, software
53
- * distributed under the Licence is distributed on an "AS IS" basis, WITHOUT
54
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
55
- * Licence for the specific language governing permissions and limitations
56
- * under the Licence.
57
- * @licend
58
- * @module
59
- */
60
-
61
- /* global console, window */
62
-
63
-
64
-
65
-
66
-
67
- /**
68
- * Font contains properties and provides methods to manage fonts
69
- */
70
- class Font {
71
- /**
72
- * Font constructor
73
- * @param {string} [family='Arial']
74
- * @param {number} [size=17]
75
- * @param {number} [bold=0]
76
- * @param {number} [italic=0]
77
- * @param {string} [variant='']
78
- */
79
- constructor(family, size, bold, italic, variant) {
80
- if (family)
81
- this.family = family;
82
- if (typeof size === 'number')
83
- this.size = size;
84
- if (bold)
85
- this.bold = bold;
86
- if (italic)
87
- this.italic = italic;
88
- if (variant)
89
- this.variant = variant;
90
- this._metrics = { ascent: -1, descent: -1, height: -1 };
91
- }
92
-
93
- /**
94
- * Finds the XML elements with typeface specifications, checks its value against the font
95
- * substitution list, replacing the `family` attribute and loading the alternative font when needed.
96
- * @param {external:jQuery} $tree - The xml element to be processed
97
- * @param {object} [options] - Optional param that can contain a `fontSubstitutions` attribute with
98
- * a substition table to be added to {@link module:AWT.Font.SUBSTITUTIONS SUBSTITUTIONS}
99
- */
100
- static checkTree($tree, options) {
101
- let substitutions = Font.SUBSTITUTIONS;
102
- // Load own fonts and remove it from the substitution table
103
- if (options && options.ownFonts) {
104
- options.ownFonts.forEach(name => {
105
- // Check WebFont as a workaround to avoid problems with a different version of `webfontloader` in agora.xtec.cat
106
- if (Font.ALREADY_LOADED_FONTS.indexOf(name) < 0 && (webfontloader__WEBPACK_IMPORTED_MODULE_2___default()) && (webfontloader__WEBPACK_IMPORTED_MODULE_2___default().load)) {
107
- webfontloader__WEBPACK_IMPORTED_MODULE_2___default().load({ custom: { families: [name] } });
108
- Font.ALREADY_LOADED_FONTS.push(name);
109
- delete substitutions[name.trim().toLowerCase()];
110
- }
111
- });
112
- }
113
-
114
- // Add custom font substitutions
115
- if (options && options.fontSubstitutions)
116
- //substitutions = Object.assign({}, substitutions, options.fontSubstitutions)
117
- substitutions = jquery__WEBPACK_IMPORTED_MODULE_0___default().extend(Object.create(substitutions), options.fontSubstitutions);
118
-
119
- if ($tree.jquery)
120
- $tree.find('style[family],font[family]').each((_n, style) => {
121
- const $style = jquery__WEBPACK_IMPORTED_MODULE_0___default()(style),
122
- name = $style.attr('family').trim().toLowerCase();
123
- if (name in substitutions) {
124
- const newName = substitutions[name];
125
- if (newName !== '') {
126
- Font.loadGoogleFont(newName);
127
- $style.attr('family', newName);
128
- }
129
- }
130
- });
131
- else {
132
- (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .findParentsWithChild */ .TQ)($tree, 'family').forEach(parent => {
133
- if (typeof parent.family === 'string') {
134
- const name = parent.family;
135
- if (Font.GOOGLEFONTS.includes(name))
136
- Font.loadGoogleFont(name);
137
- else {
138
- const newName = substitutions[name.trim().toLowerCase()];
139
- if (newName) {
140
- Font.loadGoogleFont(newName);
141
- parent.family = newName;
142
- }
143
- }
144
- }
145
- });
146
- }
147
- }
148
-
149
- /**
150
- * Try to load a specific font from [http://www.google.com/fonts]
151
- * @param {string} name - The font family name
152
- */
153
- // Check WebFont as a workaround to avoid problems with a different version of `webfontloader` in agora.xtec.cat
154
- static loadGoogleFont(name) {
155
- if (name && !Font.ALREADY_LOADED_FONTS.includes(name) && (webfontloader__WEBPACK_IMPORTED_MODULE_2___default()) && (webfontloader__WEBPACK_IMPORTED_MODULE_2___default().load)) {
156
- webfontloader__WEBPACK_IMPORTED_MODULE_2___default().load({ google: { families: [name] } });
157
- Font.ALREADY_LOADED_FONTS.push(name);
158
- }
159
- }
160
-
161
- /**
162
- * Try to load a set of Google fonts
163
- * @param {string[]} fonts - An array of font names
164
- */
165
- static loadGoogleFonts(fonts) {
166
- if (fonts && fonts.forEach)
167
- fonts.forEach(name => Font.loadGoogleFont(name));
168
- }
169
-
170
- /**
171
- * Reads the properties of this Font from an XML element
172
- * @param {external:jQuery} $xml - The xml element to be parsed
173
- * @returns {module:AWT.Font}
174
- */
175
- setProperties($xml) {
176
- if ($xml.attr('family'))
177
- this.family = $xml.attr('family');
178
- if ($xml.attr('size'))
179
- this.size = Number($xml.attr('size'));
180
- if ($xml.attr('bold'))
181
- this.bold = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .getBoolean */ .pW)($xml.attr('bold'));
182
- if ($xml.attr('italic'))
183
- this.italic = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .getBoolean */ .pW)($xml.attr('italic'));
184
- if ($xml.attr('variant'))
185
- this.variant = $xml.attr('variant');
186
- return this;
187
- }
188
-
189
- /**
190
- * Gets a object with the basic attributes needed to rebuild this instance excluding functions,
191
- * parent references, constants and also attributes retaining the default value.
192
- * The resulting object is commonly usued to serialize elements in JSON format.
193
- * @returns {object} - The resulting object, with minimal attrributes
194
- */
195
- getAttributes() {
196
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .getAttr */ .iu)(this, ['family|Arial', 'size|17', 'bold|0', 'italic|0', 'variant']);
197
- }
198
-
199
- /**
200
- * Reads the properties of this Font from a data object
201
- * @param {object} data - The data object to be parsed
202
- * @returns {module:AWT.Font}
203
- */
204
- setAttributes(data) {
205
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .setAttr */ .ob)(this, data, ['family', 'size', 'bold', 'italic', 'variant']);
206
- }
207
-
208
- /**
209
- * Allows to change the `size` member, recalculating the vertical metrics.
210
- * @param {number} size - The new size to set
211
- * @returns {module:AWT.Font}
212
- */
213
- setSize(size) {
214
- const currentSize = this.size;
215
- this.size = size;
216
- if (currentSize !== size)
217
- this._metrics.height = -1;
218
- return this;
219
- }
220
-
221
- /**
222
- * Increases or decreases the current font size by the specified amount
223
- * @param {number} amount - The amount to increase or decrease current size
224
- * @returns {module:AWT.Font}
225
- */
226
- zoom(amount) {
227
- return this.setSize(this.size + amount);
228
- }
229
-
230
- /**
231
- * Calculates the font metrics
232
- * @returns {Object} - The font metrics
233
- */
234
- getMetrics() {
235
- if (this._metrics.height < 0) {
236
- // Look for an equivalent font already calculated
237
- const font = Font.ALREADY_CALCULATED_FONTS.find(font => font.equals(this));
238
- if (font)
239
- Object.assign(this._metrics, font._metrics);
240
-
241
- if (this._metrics.height < 0) {
242
- this._calcHeight();
243
- if (this._metrics.height > 0)
244
- Font.ALREADY_CALCULATED_FONTS.push(this);
245
- }
246
- }
247
- return this._metrics;
248
- }
249
-
250
- /**
251
- * Calculates the font metrics and returns its height
252
- * @returns {number} - The font height
253
- */
254
- getHeight() {
255
- return this.getMetrics().height;
256
- }
257
-
258
- /**
259
- * Translates the Font properties into CSS statements
260
- * @param {object} css - The object where to add CSS properties. When null or undefined, a new
261
- * object will be created and returned.
262
- * @returns {object} - A set of CSS property-values pairs, ready to be used by JQuery
263
- * [.css(properties)](http://api.jquery.com/css/#css-properties).
264
- */
265
- toCss(css) {
266
- if (!css)
267
- css = {};
268
- css['font-family'] = this.family;
269
- css['font-size'] = `${this.size}px`;
270
- if (this.hasOwnProperty('bold'))
271
- css['font-weight'] = this.bold ? 'bold' : 'normal';
272
- if (this.hasOwnProperty('italic'))
273
- css['font-style'] = this.italic ? 'italic' : 'normal';
274
- if (this.hasOwnProperty('variant'))
275
- css['font-variant'] = this.variant;
276
- return css;
277
- }
278
-
279
- /**
280
- * Gets the codification of this font in a single string, suitable to be used in a `font`
281
- * CSS attribute.
282
- * @returns {string} - A string with all the CSS font properties concatenated
283
- */
284
- cssFont() {
285
- return `${this.italic ? 'italic ' : 'normal'} ${this.variant === '' ? 'normal' : this.variant} ${this.bold ? 'bold ' : 'normal'} ${this.size}px ${this.family}`;
286
- }
287
-
288
- /**
289
- * The {@link https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics TextMetrics} object used
290
- * by {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D CanvasRenderingContext2D}
291
- * does not provide a `heigth` value for rendered text.
292
- * This {@link http://stackoverflow.com/questions/1134586/how-can-you-find-the-height-of-text-on-an-html-canvas stackoverflow question}
293
- * has an excellent response by Daniel Earwicker explaining how to measure the
294
- * vertical dimension of rendered text using a `span` element.
295
- * The code has been slighty adapted to deal with Font objects.
296
- *
297
- * _Warning_: Do not call this method direcly. Use {@link module:AWT.Font#getHeight getHeight()} or {@link module:AWT.Font#getMetrics getMetrics()} instead
298
- *
299
- * @returns {module:AWT.Font}
300
- */
301
- _calcHeight() {
302
- const
303
- $text = jquery__WEBPACK_IMPORTED_MODULE_0___default()('<span/>').html('Hg').css(this.toCss()),
304
- $block = jquery__WEBPACK_IMPORTED_MODULE_0___default()('<div/>').css({ display: 'inline-block', width: '1px', height: '0px' }),
305
- $div = jquery__WEBPACK_IMPORTED_MODULE_0___default()('<div/>').append($text, $block);
306
-
307
- jquery__WEBPACK_IMPORTED_MODULE_0___default()('body').append($div);
308
- try {
309
- $block.css({ verticalAlign: 'baseline' });
310
- this._metrics.ascent = $block.offset().top - $text.offset().top;
311
- $block.css({ verticalAlign: 'bottom' });
312
- this._metrics.height = $block.offset().top - $text.offset().top;
313
- this._metrics.descent = this._metrics.height - this._metrics.ascent;
314
- } finally {
315
- $div.remove();
316
- }
317
- return this;
318
- }
319
-
320
- /**
321
- * Checks if two Font objects are equivalent
322
- * @param {module:AWT.Font} font - The Font object to compare against this one
323
- * @returns {boolean} - `true` if both objects are equivalent, `false` otherwise
324
- */
325
- equals(font) {
326
- return this.family === font.family &&
327
- this.size === font.size &&
328
- this.bold === font.bold &&
329
- this.italic === font.italic &&
330
- this.variant === font.variant;
331
- }
332
- }
333
-
334
-
335
- /**
336
- * Array of font objects with already calculated heights */
337
- Font.ALREADY_CALCULATED_FONTS = [];
338
-
339
- /**
340
- * Array of font names already loaded from Google Fonts, or generic names provided by browsers by default
341
- * See: https://developer.mozilla.org/en-US/docs/Web/CSS/font-family */
342
- Font.ALREADY_LOADED_FONTS = ['serif', 'sans-serif', 'monospace', 'cursive', 'fantasy'];
343
-
344
- /**
345
- * Google Fonts equivalent for special fonts used in some JClic projects.
346
- * More substitutions can be added to the list for specific projects indicating a
347
- * `fontSubstitutions` object in the `data-options` attribute of the HTML `div` element
348
- * containing the player.
349
- * For example:
350
- * `<div class ="JClic" data-project="demo.jclic" data-options='{"fontSubstitutions":{"arial":"Arimo"}}'/>`
351
- */
352
- Font.SUBSTITUTIONS = {
353
- // Lowercase versions of JDK Logical Fonts (see: https://docs.oracle.com/javase/tutorial/2d/text/fonts.html)
354
- 'dialog': 'sans-serif',
355
- 'dialoginput': 'sans-serif',
356
- 'monospaced': 'monospace',
357
- //'serif': 'serif',
358
- 'sansserif': 'sans-serif',
359
- // Other fonts commonly used in JClic activities, mapped to similar Google Fonts
360
- 'abc': 'Kalam',
361
- 'a.c.m.e. secret agent': 'Permanent Marker',
362
- 'comic sans ms': 'Patrick Hand',
363
- 'impact': 'Oswald',
364
- 'massallera': 'Vibur',
365
- 'memima': 'Vibur',
366
- 'memima_n1': 'Vibur',
367
- 'memima_n2': 'Vibur',
368
- 'memimas-regularalternate': 'Vibur',
369
- 'palmemim': 'Vibur',
370
- 'zurichcalligraphic': 'Felipa'
371
- };
372
- /**
373
- * Google Fonts currently used in substitutions
374
- */
375
- Font.GOOGLEFONTS = [
376
- 'Kalam', 'Permanent Marker', 'Patrick Hand', 'Oswald', 'Vibur', 'Felipa',
377
- ];
378
-
379
- Object.assign(Font.prototype, {
380
- /**
381
- * The `font-family` property
382
- * @name module:AWT.Font#family
383
- * @type {string} */
384
- family: 'Arial',
385
- /**
386
- * The font size
387
- * __Warning__: Do not change `size` directly. Use {@link module:AWT.Font#setSize setSize()} instead.
388
- * @name module:AWT.Font#size
389
- * @type {number} */
390
- size: 17,
391
- /**
392
- * The font _bold_ value
393
- * @name module:AWT.Font#bold
394
- * @type {number} */
395
- bold: 0,
396
- /**
397
- * The font _italic_ value
398
- * @name module:AWT.Font#italic
399
- * @type {number} */
400
- italic: 0,
401
- /**
402
- * The font _variant_ value
403
- * @name module:AWT.Font#variant
404
- * @type {string}*/
405
- variant: '',
406
- /**
407
- * The font *_metrics* property contains the values for `ascent`, `descent` and `height`
408
- * attributes. Vertical font metrics are calculated in
409
- * {@link module:AWT.Font#_calcHeight|_calcHeight()} as needed.
410
- * @name module:AWT.Font#_metrics
411
- * @private
412
- * @type {{ascent: number, descent: number, height: number}} */
413
- _metrics: { ascent: -1, descent: -1, height: -1 },
414
- });
415
-
416
- /**
417
- * Contains parameters and methods to draw complex color gradients
418
- */
419
- class Gradient {
420
- /**
421
- * Gradient constructor
422
- * @param {string} c1 - The initial color, in any CSS-valid form.
423
- * @param {string} c2 - The final color, in any CSS-valid form.
424
- * @param {number} [angle=0] - The inclination of the gradient relative to the horizontal line.
425
- * @param {number} [cycles=1] - The number of times the gradient will be repeated.
426
- */
427
- constructor(c1, c2, angle, cycles) {
428
- if (c1)
429
- this.c1 = c1;
430
- if (c2)
431
- this.c2 = c2;
432
- if (typeof angle === 'number')
433
- this.angle = angle % 360;
434
- if (typeof cycles === 'number')
435
- this.cycles = cycles;
436
- }
437
-
438
- /**
439
- * Reads the properties of this Gradient from an XML element
440
- * @param {external:jQuery} $xml - The xml element to be parsed
441
- * @returns {module:AWT.Gradient}
442
- */
443
- setProperties($xml) {
444
- this.c1 = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .checkColor */ .I4)($xml.attr('source'), 'black');
445
- this.c2 = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .checkColor */ .I4)($xml.attr('dest'), 'white');
446
- this.angle = Number($xml.attr('angle') || 0) % 360;
447
- this.cycles = Number($xml.attr('cycles') || 1);
448
- return this;
449
- }
450
-
451
- /**
452
- * Gets a object with the basic attributes needed to rebuild this instance excluding functions,
453
- * parent references, constants and also attributes retaining the default value.
454
- * The resulting object is commonly usued to serialize elements in JSON format.
455
- * @returns {object} - The resulting object, with minimal attrributes
456
- */
457
- getAttributes() {
458
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .getAttr */ .iu)(this, [
459
- 'c1', 'c2', 'angle|0', 'cycles|1'
460
- ]);
461
- }
462
-
463
- /**
464
- * Reads the properties of this Gradient from a data object
465
- * @param {object} data - The data object to be parsed
466
- * @returns {module:AWT.Gradient}
467
- */
468
- setAttributes(data) {
469
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .setAttr */ .ob)(this, data, ['c1', 'c2', 'angle', 'cycles']);
470
- }
471
-
472
- /**
473
- * Creates a {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasGradient|CanvasGradient}
474
- * based on the provided context and rectangle.
475
- * @param {external:CanvasRenderingContext2D} ctx - The 2D rendering context
476
- * @param {module:AWT.Rectangle} rect - The rectangle where this gradient will be applied to
477
- * @returns {module:AWT.Gradient}
478
- */
479
- getGradient(ctx, rect) {
480
- const
481
- p2 = rect.getOppositeVertex(),
482
- gradient = ctx.createLinearGradient(rect.pos.x, rect.pos.y, p2.x, p2.y),
483
- step = 1 / Math.max(this.cycles, 1);
484
- for (let i = 0; i <= this.cycles; i++)
485
- gradient.addColorStop(i * step, i % 2 ? this.c1 : this.c2);
486
- return gradient;
487
- }
488
-
489
- /**
490
- * Gets the CSS 'linear-gradient' expression of this Gradient
491
- * @returns {string} - A string ready to be used as a value for the `linear-gradient` CSS attribute
492
- */
493
- getCss() {
494
- let result = `linear-gradient(${(this.angle + 90)}deg, ${this.c1}, ${this.c2}`;
495
- for (let i = 1; i < this.cycles; i++)
496
- result = `${result}, ${i % 2 > 0 ? this.c1 : this.c2}`;
497
- return `${result})`;
498
- }
499
-
500
- /**
501
- * Checks if any of the gradient colors has transparency
502
- * @returns {boolean} - `true` if this gradient uses colors with transparency, `false` otherwise.
503
- */
504
- hasTransparency() {
505
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .colorHasTransparency */ .c0)(this.c1) || (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .colorHasTransparency */ .c0)(this.c2);
506
- }
507
- }
508
-
509
- Object.assign(Gradient.prototype, {
510
- /**
511
- * Initial color
512
- * @name module:AWT.Gradient#c1
513
- * @type {string} */
514
- c1: 'white',
515
- /**
516
- * Final color
517
- * @name module:AWT.Gradient#c2
518
- * @type {string} */
519
- c2: 'black',
520
- /**
521
- * Tilt angle
522
- * @name module:AWT.Gradient#angle
523
- * @type {number} */
524
- angle: 0,
525
- /**
526
- * Number of repetitions of the gradient
527
- * @name module:AWT.Gradient#cycles
528
- * @type {number} */
529
- cycles: 1,
530
- });
531
-
532
- /**
533
- * Contains properties used to draw lines in HTML `canvas` elements.
534
- * @see {@link http://bucephalus.org/text/CanvasHandbook/CanvasHandbook.html#line-caps-and-joins}
535
- */
536
- class Stroke {
537
- /**
538
- * Stroke constructor
539
- * @param {number} [lineWidth=1] - The line width of the stroke
540
- * @param {string} [lineCap='butt'] - The line ending type. Possible values are: `butt`, `round`
541
- * and `square`.
542
- * @param {string} [lineJoin='miter'] - The type of drawing used when two lines join. Possible
543
- * values are: `round`, `bevel` and `miter`.
544
- * @param {number} [miterLimit=10] - The ratio between the miter length and half `lineWidth`.
545
- */
546
- constructor(lineWidth, lineCap, lineJoin, miterLimit) {
547
- if (typeof lineWidth === 'number')
548
- this.lineWidth = lineWidth;
549
- if (lineCap)
550
- this.lineCap = lineCap;
551
- if (lineJoin)
552
- this.lineJoin = lineJoin;
553
- if (typeof miterLimit === 'number')
554
- this.miterLimit = miterLimit;
555
- }
556
-
557
- /**
558
- * Gets a object with the basic attributes needed to rebuild this instance excluding functions,
559
- * parent references, constants and also attributes retaining the default value.
560
- * The resulting object is commonly usued to serialize elements in JSON format.
561
- * @returns {object} - The resulting object, with minimal attrributes
562
- */
563
- getAttributes() {
564
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .getAttr */ .iu)(this, [
565
- 'lineWidth|1', 'lineCap|butt', 'lineJoin|miter', 'miterLimit|10',
566
- ]);
567
- }
568
-
569
- /**
570
- * Reads the properties of this Stroke from a data object
571
- * @param {object} data - The data object to be parsed
572
- * @returns {module:AWT.Stroke}
573
- */
574
- setAttributes(data) {
575
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .setAttr */ .ob)(this, data, ['lineWidth', 'lineCap', 'lineJoin', 'miterLimit']);
576
- }
577
-
578
- /**
579
- * Sets the properties of this stroke to a CanvasRenderingContext2D
580
- * @param {external:CanvasRenderingContext2D} ctx - The canvas 2D rendering context
581
- * @returns {external:CanvasRenderingContext2D}
582
- */
583
- setStroke(ctx) {
584
- ctx.lineWidth = this.lineWidth;
585
- ctx.lineCap = this.lineCap;
586
- ctx.lineJoin = this.lineJoin;
587
- ctx.miterLimit = this.miterLimit;
588
- return ctx;
589
- }
590
- }
591
-
592
- Object.assign(Stroke.prototype, {
593
- /**
594
- * The line width
595
- * @name module:AWT.Stroke#lineWidth
596
- * @type {number} */
597
- lineWidth: 1.0,
598
- /**
599
- * The line ending type (`butt`, `round` or `square`)
600
- * @name module:AWT.Stroke#lineCap
601
- * @type {string} */
602
- lineCap: 'butt',
603
- /**
604
- * The drawing used when two lines join (`round`, `bevel` or `miter`)
605
- * @name module:AWT.Stroke#lineJoin
606
- * @type {string} */
607
- lineJoin: 'miter',
608
- /**
609
- * Ratio between the miter length and half `lineWidth`
610
- * @name module:AWT.Stroke#miterLimit
611
- * @type {number} */
612
- miterLimit: 10.0,
613
- });
614
-
615
- /**
616
- * Contains the `x` andy `y` coordinates of a point, and provides some useful methods.
617
- */
618
- class Point {
619
- /**
620
- * Point constructor
621
- * @param {number|Point} x - When `x` is an `Point` object, a clone of it will be created.
622
- * @param {number} [y] - Not used when `x` is an `Point`
623
- */
624
- constructor(x, y) {
625
- if (x instanceof Point) {
626
- // Special case: constructor passing another point as unique parameter
627
- this.x = x.x;
628
- this.y = x.y;
629
- } else {
630
- this.x = x || 0;
631
- this.y = y || 0;
632
- }
633
- }
634
-
635
- /**
636
- * Reads the properties of this Point from an XML element
637
- * @param {external:jQuery} $xml - The xml element to be parsed
638
- * @returns {module:AWT.Point}
639
- */
640
- setProperties($xml) {
641
- this.x = Number($xml.attr('x'));
642
- this.y = Number($xml.attr('y'));
643
- return this;
644
- }
645
-
646
- /**
647
- * Gets a object with the basic attributes needed to rebuild this instance excluding functions,
648
- * parent references, constants and also attributes retaining the default value.
649
- * The resulting object is commonly usued to serialize elements in JSON format.
650
- * @returns {object} - The resulting object, with minimal attrributes
651
- */
652
- getAttributes() {
653
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .getAttr */ .iu)(this, ['x', 'y']);
654
- }
655
-
656
- /**
657
- * Reads the properties of this Point from a data object
658
- * @param {object} data - The data object to be parsed
659
- * @returns {module:AWT.Point}
660
- */
661
- setAttributes(data) {
662
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .setAttr */ .ob)(this, data, ['x', 'y']);
663
- }
664
-
665
- /**
666
- * Moves this Point to a new position, by a specified displacement
667
- * @param {Point|Dimension} delta - The amount to move
668
- * @returns {module:AWT.Point}
669
- */
670
- moveBy(delta) {
671
- this.x += delta.x || delta.width || 0;
672
- this.y += delta.y || delta.height || 0;
673
- return this;
674
- }
675
-
676
- /**
677
- * Moves this Point to a new position
678
- * @param {number|Point} newPos - The new position, or a x coordinate
679
- * @param {number} [y] - `null` or `undefined` when `newPos` is a Point
680
- * @returns {module:AWT.Point}
681
- */
682
- moveTo(newPos, y) {
683
- if (typeof newPos === 'number') {
684
- this.x = newPos;
685
- this.y = y;
686
- } else {
687
- this.x = newPos.x;
688
- this.y = newPos.y;
689
- }
690
- return this;
691
- }
692
-
693
- /**
694
- * Multiplies the `x` and `y` coordinates by a specified `delta`
695
- * @param {Point|Dimension} delta - The amount to multiply by.
696
- * @returns {module:AWT.Point}
697
- */
698
- multBy(delta) {
699
- this.x *= delta.x || delta.width || 0;
700
- this.y *= delta.y || delta.height || 0;
701
- return this;
702
- }
703
-
704
- /**
705
- * Checks if two points are at the same place
706
- * @param {module:AWT.Point} p - The Point to check against to
707
- * @returns {boolean}
708
- */
709
- equals(p) {
710
- return this.x === p.x && this.y === p.y;
711
- }
712
-
713
- /**
714
- * Calculates the distance between two points
715
- * @param {module:AWT.Point} point - The Point to calculate the distance against to
716
- * @returns {number} - The distance between the two points.
717
- */
718
- distanceTo(point) {
719
- return Math.sqrt(Math.pow(this.x - point.x, 2), Math.pow(this.y - point.y, 2));
720
- }
721
-
722
- /**
723
- * Clones this point
724
- * @returns {module:AWT.Point}
725
- */
726
- clone() {
727
- return new Point(this);
728
- }
729
- }
730
-
731
- Object.assign(Point.prototype, {
732
- /**
733
- * @name module:AWT.Point#x
734
- * @type {number} */
735
- x: 0,
736
- /**
737
- * @name module:AWT.Point#y
738
- * @type {number} */
739
- y: 0,
740
- });
741
-
742
- /**
743
- * This class encapsulates `width` and `height` properties.
744
- */
745
- class Dimension {
746
- /**
747
- * Dimension constructor
748
- * @param {number|Point} w - The width of this Dimension, or the upper-left vertex of a
749
- * virtual Rectangle
750
- * @param {number|Point} h - The height of this Dimension, or the bottom-right vertex of a
751
- * virtual Rectangle
752
- */
753
- constructor(w, h) {
754
- if (w instanceof Point && h instanceof Point) {
755
- this.width = h.x - w.x;
756
- this.height = h.y - w.y;
757
- } else {
758
- this.width = w || 0;
759
- this.height = h || 0;
760
- }
761
- }
762
-
763
- /**
764
- * Reads the properties of this Dimension from an XML element
765
- * @param {external:jQuery} $xml - The xml element to be parsed
766
- * @returns {module:AWT.Dimension}
767
- */
768
- setProperties($xml) {
769
- this.width = Number($xml.attr('width'));
770
- this.height = Number($xml.attr('height'));
771
- return this;
772
- }
773
-
774
- /**
775
- * Gets a object with the basic attributes needed to rebuild this instance excluding functions,
776
- * parent references, constants and also attributes retaining the default value.
777
- * The resulting object is commonly usued to serialize elements in JSON format.
778
- * @returns {object} - The resulting object, with minimal attrributes
779
- */
780
- getAttributes() {
781
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .getAttr */ .iu)(this, ['width', 'height']);
782
- }
783
-
784
- /**
785
- * Reads the properties of this Dimension from a data object
786
- * @param {object} data - The data object to be parsed
787
- * @returns {module:AWT.Dimension}
788
- */
789
- setAttributes(data) {
790
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .setAttr */ .ob)(this, data, ['width', 'height']);
791
- }
792
-
793
- /**
794
- * Check if two dimensions are equivalent
795
- * @param {module:AWT.Dimension} d
796
- * @returns {boolean}
797
- */
798
- equals(d) {
799
- return this.width === d.width && this.height === d.height;
800
- }
801
-
802
- /**
803
- * Multiplies the `w` and `h` co-ordinates by a specified `delta`
804
- * @param {Point|Dimension} delta
805
- * @returns {module:AWT.Dimension}
806
- */
807
- multBy(delta) {
808
- this.width *= delta.x || delta.width || 0;
809
- this.height *= delta.y || delta.height || 0;
810
- return this;
811
- }
812
-
813
- /**
814
- * Sets new values for width and height.
815
- * `width` can be a number or another `Dimension` object
816
- * @param {number|Dimension} width - The new width, or a full Dimension to copy it from.
817
- * @param {number} [height] - Not used when `width` is a Dimension
818
- * @returns {module:AWT.Dimension}
819
- */
820
- setDimension(width, height) {
821
- if (width instanceof Dimension) {
822
- height = width.height;
823
- width = width.width;
824
- }
825
- this.width = width;
826
- this.height = height;
827
- return this;
828
- }
829
-
830
- /**
831
- * Calculates the area of a Rectangle with this dimension
832
- * @returns {number} The resulting area
833
- */
834
- getSurface() {
835
- return this.width * this.height;
836
- }
837
- }
838
-
839
- Object.assign(Dimension.prototype, {
840
- /**
841
- * @name module:AWT.Dimension#width
842
- * @type {number} */
843
- width: 0,
844
- /**
845
- * @name module:AWT.Dimension#height
846
- * @type {number} */
847
- height: 0,
848
- });
849
-
850
- /**
851
- * Shape is a generic abstract class for rectangles, ellipses and stroke-free shapes.
852
- * @abstract
853
- */
854
- class Shape {
855
- /**
856
- * Shape constructor
857
- * @param {module:AWT.Point} pos - The top-left coordinates of this Shape
858
- */
859
- constructor(pos) {
860
- this.pos = pos || new Point();
861
- }
862
-
863
- /**
864
- * Shifts the shape a specified amount in horizontal and vertical directions
865
- * @param {Point|Dimension} delta - The amount to shift the Shape
866
- * @returns {module:AWT.Shape}
867
- */
868
- moveBy(delta) {
869
- this.pos.moveBy(delta);
870
- return this;
871
- }
872
-
873
- /**
874
- * Moves this shape to a new position
875
- * @param {module:AWT.Point} newPos - The new position of the shape
876
- * @returns {module:AWT.Shape}
877
- */
878
- moveTo(newPos) {
879
- this.pos.moveTo(newPos);
880
- return this;
881
- }
882
-
883
- /**
884
- * Gets the enclosing {@link module:AWT.Rectangle Rectangle} of this Shape.
885
- * @returns {module:AWT.Rectangle}
886
- */
887
- getBounds() {
888
- return new Rectangle(this.pos);
889
- }
890
-
891
- /**
892
- * Checks if two shapes are equivalent.
893
- * @param {module:AWT.Shape} p - The Shape to compare against
894
- * @returns {boolean}
895
- */
896
- equals(p) {
897
- return this.pos.equals(p.pos);
898
- }
899
-
900
- /**
901
- * Multiplies the dimension of the Shape by the specified `delta` amount.
902
- * @param {Point|Dimension} _delta - Object containing the X and Y ratio to be scaled.
903
- * @returns {module:AWT.Shape}
904
- */
905
- scaleBy(_delta) {
906
- // Nothing to scale in abstract shapes
907
- return this;
908
- }
909
-
910
- /**
911
- * Gets a clone of this shape moved to the `pos` component of the rectangle and scaled
912
- * by its `dim` value.
913
- * @param {module:AWT.Rectangle} rect - The rectangle to be taken as a base for moving and scaling
914
- * this shape.
915
- * @returns {module:AWT.Shape}
916
- */
917
- getShape(rect) {
918
- return this.clone().scaleBy(rect.dim).moveBy(rect.pos);
919
- }
920
-
921
- /**
922
- * Checks if the provided {@link module:AWT.Point} is inside this shape.
923
- * @param {module:AWT.Point} _p - The point to check
924
- * @returns {boolean}
925
- */
926
- contains(_p) {
927
- // Nothing to check in abstract shapes
928
- return false;
929
- }
930
-
931
- /**
932
- * Checks if the provided {@link module:AWT.Rectangle Rectangle} `r` intersects with this shape.
933
- * @param {module:AWT.Rectangle} _r
934
- * @returns {boolean}
935
- */
936
- intersects(_r) {
937
- // Nothing to check in abstract shapes
938
- return false;
939
- }
940
-
941
- /**
942
- * Fills the Shape with the current style in the provided HTML canvas context
943
- * @param {external:CanvasRenderingContext2D} ctx - The canvas 2D rendering context where to fill this shape.
944
- * @param {module:AWT.Rectangle} [dirtyRegion] - The context region to be updated. Used as clipping
945
- * region when drawing.
946
- * @returns {external:CanvasRenderingContext2D} - The provided rendering context
947
- */
948
- fill(ctx, dirtyRegion) {
949
- ctx.save();
950
- if (dirtyRegion && dirtyRegion.getSurface() > 0) {
951
- // Clip the dirty region
952
- ctx.beginPath();
953
- ctx.rect(dirtyRegion.pos.x, dirtyRegion.pos.y, dirtyRegion.dim.width, dirtyRegion.dim.height);
954
- ctx.clip();
955
- }
956
- // Prepare shape path and fill
957
- this.preparePath(ctx);
958
- ctx.fill();
959
- ctx.restore();
960
- return ctx;
961
- }
962
-
963
- /**
964
- * Draws this shape in the provided HTML canvas 2D rendering context.
965
- * @param {external:CanvasRenderingContext2D} ctx - The canvas 2D rendering context where to draw the shape.
966
- * @returns {external:CanvasRenderingContext2D} - The provided rendering context
967
- */
968
- stroke(ctx) {
969
- this.preparePath(ctx);
970
- ctx.stroke();
971
- return ctx;
972
- }
973
-
974
- /**
975
- * Prepares an HTML canvas 2D rendering context with a path that can be used to stroke a line,
976
- * to fill a surface or to define a clipping region.
977
- * @param {external:CanvasRenderingContext2D} ctx
978
- * @returns {external:CanvasRenderingContext2D} - The provided rendering context
979
- */
980
- preparePath(ctx) {
981
- // Nothing to do in abstract shapes
982
- return ctx;
983
- }
984
-
985
- /**
986
- * Creates a clipping region on the specified HTML canvas 2D rendering context
987
- * @param {external:CanvasRenderingContext2D} ctx - The rendering context
988
- * @param {string} [fillRule='nonzero'] - Can be 'nonzero' (default when not set) or 'evenodd'
989
- * @returns {external:CanvasRenderingContext2D} - The provided rendering context
990
- */
991
- clip(ctx, fillRule) {
992
- this.preparePath(ctx);
993
- ctx.clip(fillRule || 'nonzero');
994
- return ctx;
995
- }
996
-
997
- /**
998
- * Shorthand method for determining if a Shape is an {@link module:AWT.Rectangle Rectangle}
999
- * @returns {boolean}
1000
- */
1001
- isRect() {
1002
- return false;
1003
- }
1004
-
1005
- /**
1006
- * Overwrites the original 'Object.toString' method with a more descriptive text
1007
- * @returns {string}
1008
- */
1009
- toString() {
1010
- return `Shape enclosed in ${this.getBounds().getCoords()}`;
1011
- }
1012
-
1013
- /**
1014
- * Reads the properties of this Shape from a data object
1015
- * @param {object} data - The data object to be parsed
1016
- * @returns {module:AWT.Shape}
1017
- */
1018
- setAttributes(data) {
1019
- return Shape.buildShape(data);
1020
- /*
1021
- return setAttr(this, data, [
1022
- 'type',
1023
- { key: 'pos', fn: Point },
1024
- ]);
1025
- */
1026
- }
1027
-
1028
- /**
1029
- * Builds a shape based on the provided `data` object.
1030
- * Data should contain a 'type' member, specifying the type of shape requested ('rect', 'ellipse', 'rectangle' or 'path')
1031
- * @param {object} data - Specific data for this shape
1032
- * @returns {module:AWT.Shape}
1033
- */
1034
- static buildShape(data) {
1035
- const shapeType = (data.type === 'rect' && Rectangle) || (data.type === 'ellipse' && Ellipse) || (data.type === 'path' && Path) || null;
1036
- if (!shapeType) {
1037
- console.log('unknown shape:', data);
1038
- } else
1039
- return (new shapeType()).setAttributes(data);
1040
- }
1041
- }
1042
-
1043
- Object.assign(Shape.prototype, {
1044
- /**
1045
- * Shape type id
1046
- * @name module:AWT.Shape#type
1047
- * @type {string} */
1048
- type: 'shape',
1049
- /**
1050
- * The current position of the shape
1051
- * @name module:AWT.Shape#pos
1052
- * @type {module:AWT.Point} */
1053
- pos: new Point(),
1054
- /**
1055
- * The type of shape (Rectangle, ellipse, path...)
1056
- * @name module:AWT.Shape#type
1057
- * @type {string} */
1058
- type: 'shape',
1059
- });
1060
-
1061
- /**
1062
- * The rectangular {@link module:AWT.Shape} accepts five different sets of parameters:
1063
- * @example
1064
- * // Calling Rectangle() with different sets of parameters
1065
- * // A Point and a Dimension:
1066
- * new Rectangle(pos, dim)
1067
- * // Another Rectangle, to be cloned:
1068
- * new Rectangle(rect)
1069
- * // Two Point objects containing the coordinates of upper-left and lower-right vertexs:
1070
- * new Rectangle(p0, p1)
1071
- * // An array of four numbers with the coordinates of the same vertexs:
1072
- * new Rectangle([x0, y0, x1, y1])
1073
- * // Four single numbers, meaning the same coordinates as above:
1074
- * new Rectangle(x0, y0, x1, y1)
1075
- * @extends module:AWT.Shape
1076
- */
1077
- class Rectangle extends Shape {
1078
- /**
1079
- * Rectangle constructor
1080
- * @param {Point|Rectangle|number|number[]} pos
1081
- * @param {Dimension|number} [dim]
1082
- * @param {number} [w]
1083
- * @param {number} [h]
1084
- */
1085
- constructor(pos, dim, w, h) {
1086
- let p = pos, d = dim;
1087
- // Special case: constructor with a Rectangle as a unique parameter
1088
- if (pos instanceof Rectangle) {
1089
- d = new Dimension(pos.dim.width, pos.dim.height);
1090
- p = new Point(pos.pos.x, pos.pos.y);
1091
- } else if (pos instanceof Point) {
1092
- p = new Point(pos.x, pos.y);
1093
- if (dim instanceof Dimension)
1094
- d = new Dimension(dim.width, dim.height);
1095
- } else if (pos instanceof Array) {
1096
- // Assume `pos` is an array of numbers indicating: x0, y0, x1, y1
1097
- p = new Point(pos[0], pos[1]);
1098
- d = new Dimension(pos[2] - pos[0], pos[3] - pos[1]);
1099
- } else if (typeof w === 'number' && typeof h === 'number') {
1100
- // width and height passed. Treat all parameters as co-ordinates:
1101
- p = new Point(pos, dim);
1102
- d = new Dimension(w, h);
1103
- }
1104
- super(p);
1105
-
1106
- if (d instanceof Dimension)
1107
- this.dim = d;
1108
- else if (d instanceof Point)
1109
- this.dim = new Dimension(d.x - this.pos.x, d.y - this.pos.y);
1110
- else
1111
- this.dim = new Dimension();
1112
-
1113
- this.type = 'rect';
1114
- }
1115
-
1116
- /**
1117
- * Gets the enclosing {@link module:AWT.Rectangle Rectangle} of this Shape.
1118
- * @returns {module:AWT.Rectangle}
1119
- */
1120
- getBounds() {
1121
- return this;
1122
- }
1123
-
1124
- /**
1125
- * Sets this Rectangle the position and dimension of another one
1126
- * @param {module:AWT.Rectangle} rect
1127
- * @returns {module:AWT.Rectangle}
1128
- */
1129
- setBounds(rect) {
1130
- if (!rect)
1131
- rect = new Rectangle();
1132
- this.pos.x = rect.pos.x;
1133
- this.pos.y = rect.pos.y;
1134
- this.dim.width = rect.dim.width;
1135
- this.dim.height = rect.dim.height;
1136
- return this;
1137
- }
1138
-
1139
- /**
1140
- * Checks if two shapes are equivalent.
1141
- * @param {module:AWT.Shape} r - The Shape to compare against
1142
- * @returns {boolean}
1143
- */
1144
- equals(r) {
1145
- return r instanceof Rectangle && this.pos.equals(r.pos) && this.dim.equals(r.dim);
1146
- }
1147
-
1148
- /**
1149
- * Clones this Rectangle
1150
- * @returns {module:AWT.Rectangle}
1151
- */
1152
- clone() {
1153
- return new Rectangle(this);
1154
- }
1155
-
1156
- /**
1157
- * Multiplies the dimension of the Shape by the specified `delta` amount.
1158
- * @param {Point|Dimension} delta - Object containing the X and Y ratio to be scaled.
1159
- * @returns {module:AWT.Rectangle}
1160
- */
1161
- scaleBy(delta) {
1162
- this.pos.multBy(delta);
1163
- this.dim.multBy(delta);
1164
- return this;
1165
- }
1166
-
1167
- /**
1168
- * Expands the boundaries of this shape. This affects the current position and dimension.
1169
- * @param {number} dx - The amount to grow (or decrease) in horizontal direction
1170
- * @param {number} dy - The amount to grow (or decrease) in vertical direction
1171
- * @returns {module:AWT.Rectangle}
1172
- */
1173
- grow(dx, dy) {
1174
- this.pos.x -= dx;
1175
- this.pos.y -= dy;
1176
- this.dim.width += 2 * dx;
1177
- this.dim.height += 2 * dy;
1178
- return this;
1179
- }
1180
-
1181
- /**
1182
- * Gets the {@link module:AWT.Point} corresponding to the lower-right vertex of the Rectangle.
1183
- * @returns {module:AWT.Point}
1184
- */
1185
- getOppositeVertex() {
1186
- return new Point(this.pos.x + this.dim.width, this.pos.y + this.dim.height);
1187
- }
1188
-
1189
- /**
1190
- * Adds the boundaries of another shape to the current one
1191
- * @param {module:AWT.Shape} shape - The {@link module:AWT.Shape} to be added
1192
- * @returns {module:AWT.Rectangle}
1193
- */
1194
- add(shape) {
1195
- const
1196
- myP2 = this.getOppositeVertex(),
1197
- rectP2 = shape.getBounds().getOppositeVertex();
1198
-
1199
- this.pos.moveTo(
1200
- Math.min(this.pos.x, shape.getBounds().pos.x),
1201
- Math.min(this.pos.y, shape.getBounds().pos.y));
1202
- this.dim.setDimension(
1203
- Math.max(myP2.x, rectP2.x) - this.pos.x,
1204
- Math.max(myP2.y, rectP2.y) - this.pos.y);
1205
- return this;
1206
- }
1207
-
1208
- //
1209
- // Inherits the documentation of `contains` in Shape
1210
- contains(p) {
1211
- const p2 = this.getOppositeVertex();
1212
- return p.x >= this.pos.x && p.x <= p2.x && p.y >= this.pos.y && p.y <= p2.y;
1213
- }
1214
-
1215
- //
1216
- // Inherits the documentation of `intersects` in Shape
1217
- intersects(r) {
1218
- const
1219
- p1 = this.pos, p2 = this.getOppositeVertex(),
1220
- r1 = r.pos, r2 = r.getOppositeVertex();
1221
- return r2.x >= p1.x && r1.x <= p2.x && r2.y >= p1.y && r1.y <= p2.y;
1222
- }
1223
-
1224
- //
1225
- // Inherits the documentation of `preparePath` in Shape
1226
- preparePath(ctx) {
1227
- ctx.beginPath();
1228
- ctx.rect(this.pos.x, this.pos.y, this.dim.width, this.dim.height);
1229
- return ctx;
1230
- }
1231
-
1232
- //
1233
- // Inherits the documentation of `getSurface` in Shape
1234
- getSurface() {
1235
- return this.dim.getSurface();
1236
- }
1237
-
1238
- //
1239
- // Inherits the documentation of `isEmpty` in Shape
1240
- isEmpty() {
1241
- return this.getSurface() === 0;
1242
- }
1243
-
1244
- //
1245
- // Inherits the documentation of `isRect` in Shape
1246
- isRect() {
1247
- return true;
1248
- }
1249
-
1250
- //
1251
- // Inherits the documentation of `toString` in Shape
1252
- toString() {
1253
- return `Rectangle ${this.getCoords()}`;
1254
- }
1255
-
1256
- /**
1257
- * Gets a string with the co-ordinates of the upper-left and lower-right vertexs of this rectangle,
1258
- * (with values rounded to int)
1259
- * @returns {string}
1260
- */
1261
- getCoords() {
1262
- return `[${Math.round(this.pos.x)},${Math.round(this.pos.y)},${Math.round(this.pos.x + this.dim.width)},${Math.round(this.pos.y + this.dim.height)}]`;
1263
- }
1264
-
1265
- /**
1266
- * Gets a object with the basic attributes needed to rebuild this instance excluding functions,
1267
- * parent references, constants and also attributes retaining the default value.
1268
- * The resulting object is commonly usued to serialize elements in JSON format.
1269
- * @returns {object} - The resulting object, with minimal attrributes
1270
- */
1271
- getAttributes() {
1272
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .getAttr */ .iu)(this, ['type', 'pos', 'dim']);
1273
- }
1274
-
1275
- /**
1276
- * Reads the properties of this Rectangle from a data object
1277
- * @param {object} data - The data object to be parsed
1278
- * @returns {module:AWT.Rectangle}
1279
- */
1280
- setAttributes(data) {
1281
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .setAttr */ .ob)(this, data, [
1282
- 'type',
1283
- { key: 'pos', fn: Point },
1284
- { key: 'dim', fn: Dimension },
1285
- ]);
1286
- }
1287
- }
1288
-
1289
- Object.assign(Rectangle.prototype, {
1290
- /**
1291
- * Shape type id
1292
- * @name module:AWT.Rectangle#type
1293
- * @type {string} */
1294
- type: 'rect',
1295
- /**
1296
- * The {@link module:AWT.Dimension Dimension} of the Rectangle
1297
- * @name module:AWT.Rectangle#dim
1298
- * @type {module:AWT.Dimension} */
1299
- dim: new Dimension(),
1300
- });
1301
-
1302
- /**
1303
- * The Ellipse shape has the same constructor options as {@link module:AWT.Rectangle Rectangle}
1304
- * @extends module:AWT.Rectangle
1305
- */
1306
- class Ellipse extends Rectangle {
1307
- /**
1308
- * Ellipse constructor
1309
- * @param {Point|Rectangle|number|number[]} pos
1310
- * @param {Dimension|number} [dim]
1311
- * @param {number} [w]
1312
- * @param {number} [h]
1313
- */
1314
- constructor(pos, dim, w, h) {
1315
- super(pos, dim, w, h);
1316
- }
1317
-
1318
- //
1319
- // Inherits the documentation of `preparePath` in Rectangle
1320
- preparePath(ctx) {
1321
-
1322
- // Using the solution 'drawEllipseWithBezier' proposed by Steve Tranby in:
1323
- // [http://jsbin.com/sosugenegi/1/edit] as a response to:
1324
- // [http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas]
1325
- // Thanks Steve!!
1326
-
1327
- const kappa = 0.5522848,
1328
- ox = kappa * this.dim.width / 2, // control point offset horizontal
1329
- oy = kappa * this.dim.height / 2, // control point offset vertical
1330
- xe = this.pos.x + this.dim.width, // x-end
1331
- ye = this.pos.y + this.dim.height, // y-end
1332
- xm = this.pos.x + this.dim.width / 2, // x-middle
1333
- ym = this.pos.y + this.dim.height / 2; // y-middle
1334
-
1335
- ctx.beginPath();
1336
- ctx.moveTo(this.pos.x, ym);
1337
- ctx.bezierCurveTo(this.pos.x, ym - oy, xm - ox, this.pos.y, xm, this.pos.y);
1338
- ctx.bezierCurveTo(xm + ox, this.pos.y, xe, ym - oy, xe, ym);
1339
- ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
1340
- ctx.bezierCurveTo(xm - ox, ye, this.pos.x, ym + oy, this.pos.x, ym);
1341
- ctx.closePath();
1342
- return ctx;
1343
- }
1344
-
1345
- //
1346
- // Inherits the documentation of `contains` in Shape
1347
- contains(p) {
1348
- // First check if the point is inside the enclosing rectangle
1349
- let result = super.contains(p);
1350
- if (result) {
1351
- const
1352
- rx = this.dim.width / 2,
1353
- ry = this.dim.height / 2,
1354
- cx = this.pos.x + rx,
1355
- cy = this.pos.y + ry;
1356
- // Apply the general equation of an ellipse
1357
- // See: [http://math.stackexchange.com/questions/76457/check-if-a-point-is-within-an-ellipse]
1358
- // rx and ry are > 0 because we are inside the enclosing rect,
1359
- // so don't care about division by zero
1360
- result = Math.pow(p.x - cx, 2) / Math.pow(rx, 2) + Math.pow(p.y - cy, 2) / Math.pow(ry, 2) <= 1;
1361
- }
1362
- return result;
1363
- }
1364
-
1365
- //
1366
- // Inherits the documentation of `getSurface` in Rectangle
1367
- getSurface() {
1368
- return Math.PI * this.dim.width / 2 * this.dim.height / 2;
1369
- }
1370
-
1371
- //
1372
- // Inherits the documentation of `equals` in Rectangle
1373
- equals(e) {
1374
- return e instanceof Ellipse && super.equals(e);
1375
- }
1376
-
1377
- //
1378
- // Inherits the documentation of `clone` in Rectangle
1379
- clone() {
1380
- return new Ellipse(this.pos, this.dim);
1381
- }
1382
-
1383
- //
1384
- // Inherits the documentation of `isRect` in Rectangle
1385
- isRect() {
1386
- return false;
1387
- }
1388
-
1389
- //
1390
- // Inherits the documentation of `toString` in Shape
1391
- toString() {
1392
- return `Ellipse enclosed in ${this.getCoords()}`;
1393
- }
1394
- }
1395
-
1396
- Object.assign(Ellipse.prototype, {
1397
- /**
1398
- * Shape type id
1399
- * @name module:AWT.Ellipse#type
1400
- * @type {string} */
1401
- type: 'ellipse',
1402
- });
1403
-
1404
- /**
1405
- * A `Path` is a {@link module:AWT.Shape} formed by a serie of strokes, represented by
1406
- * {@link module:AWT.PathStroke} objects
1407
- * @extends module:AWT.Shape
1408
- */
1409
- class Path extends Shape {
1410
- /**
1411
- * Path constructor
1412
- * @param {module:AWT.PathStroke[]} strokes - The array of {@link module:AWT.PathStroke} objects defining this Path.
1413
- */
1414
- constructor(strokes) {
1415
- super();
1416
- // Deep copy of the array of strokes
1417
- if (strokes)
1418
- this.setStrokes(strokes);
1419
- }
1420
-
1421
- setStrokes(strokes) {
1422
- this.strokes = [];
1423
- // In [Shaper](Shaper.html) objects, strokes have `action` instead of `type` and `data` instead of `points`
1424
- strokes.forEach(str => this.strokes.push(new PathStroke(str.type || str.action, str.points || str.data)));
1425
- // Calculate the enclosing rectangle
1426
- this.enclosing = new Rectangle();
1427
- this.enclosingPoints = [];
1428
- this.calcEnclosingRect();
1429
- this.pos = this.enclosing.pos;
1430
- return this;
1431
- }
1432
-
1433
- //
1434
- // Inherits the documentation of `clone` in Shape
1435
- clone() {
1436
- return new Path(this.strokes.map(str => str.clone()));
1437
- }
1438
-
1439
- /**
1440
- * Adds a {@link module:AWT.PathStroke} to `strokes`
1441
- * @param {module:AWT.PathStroke} stroke
1442
- */
1443
- addStroke(stroke) {
1444
- this.strokes.push(stroke);
1445
- return this;
1446
- }
1447
-
1448
- /**
1449
- * Calculates the polygon and the rectangle that (approximately) encloses this shape
1450
- * @returns {module:AWT.Rectangle}
1451
- */
1452
- calcEnclosingRect() {
1453
- this.enclosingPoints = [];
1454
- let last = new Point();
1455
- this.strokes.forEach(str => {
1456
- str.getEnclosingPoints(last).forEach(pt => {
1457
- last = new Point(pt);
1458
- this.enclosingPoints.push(last);
1459
- });
1460
- });
1461
-
1462
- let l = this.enclosingPoints.length;
1463
- if (l > 1 && this.enclosingPoints[0].equals(this.enclosingPoints[l - 1])) {
1464
- this.enclosingPoints.pop();
1465
- l--;
1466
- }
1467
- const
1468
- p0 = new Point(this.enclosingPoints[0]),
1469
- p1 = new Point(this.enclosingPoints[0]);
1470
-
1471
- for (let k = 1; k < l; k++) {
1472
- const p = this.enclosingPoints[k];
1473
- // Check if `p` is at left or above `p0`
1474
- p0.x = Math.min(p.x, p0.x);
1475
- p0.y = Math.min(p.y, p0.y);
1476
- // Check if `p` is at right or below `p1`
1477
- p1.x = Math.max(p.x, p1.x);
1478
- p1.y = Math.max(p.y, p1.y);
1479
- }
1480
- this.enclosing.setBounds(new Rectangle(p0, new Dimension(p0, p1)));
1481
- return this.enclosing;
1482
- }
1483
-
1484
- //
1485
- // Inherits the documentation of `getBounds` in Shape
1486
- getBounds() {
1487
- return this.enclosing;
1488
- }
1489
-
1490
- //
1491
- // Inherits the documentation of `moveBy` in Shape
1492
- moveBy(delta) {
1493
- this.strokes.forEach(str => str.moveBy(delta));
1494
- this.enclosingPoints.forEach(pt => pt.moveBy(delta));
1495
- this.enclosing.moveBy(delta);
1496
- return this;
1497
- }
1498
-
1499
- //
1500
- // Inherits the documentation of `moveTo` in Shape
1501
- moveTo(newPos) {
1502
- return this.moveBy(new Dimension(newPos.x - this.pos.x, newPos.y - this.pos.y));
1503
- }
1504
-
1505
- //
1506
- // Inherits the documentation of `equals` in Shape
1507
- // TODO: Implement comparision of complex paths
1508
- equals(_p) {
1509
- return false;
1510
- }
1511
-
1512
- //
1513
- // Inherits the documentation of `scaleBy` in Shape
1514
- scaleBy(delta) {
1515
- this.strokes.forEach(str => str.multBy(delta));
1516
- this.enclosingPoints.forEach(pt => pt.multBy(delta));
1517
- this.enclosing.scaleBy(delta);
1518
- return this;
1519
- }
1520
-
1521
- //
1522
- // Inherits the documentation of `contains` in Shape
1523
- contains(p) {
1524
- let result = this.enclosing.contains(p);
1525
- if (result) {
1526
- // Let's see if the point really lies inside the polygon formed by enclosingPoints
1527
- // Using the "Ray casting algorithm" described in [https://en.wikipedia.org/wiki/Point_in_polygon]
1528
- const N = this.enclosingPoints.length;
1529
- let
1530
- xinters = 0,
1531
- counter = 0,
1532
- p1 = this.enclosingPoints[0];
1533
-
1534
- for (let i = 1; i <= N; i++) {
1535
- const p2 = this.enclosingPoints[i % N];
1536
- if (p.y > Math.min(p1.y, p2.y)) {
1537
- if (p.y <= Math.max(p1.y, p2.y)) {
1538
- if (p.x <= Math.max(p1.x, p2.x)) {
1539
- if (p1.y !== p2.y) {
1540
- xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
1541
- if (p1.x === p2.x || p.x <= xinters)
1542
- counter++;
1543
- }
1544
- }
1545
- }
1546
- }
1547
- p1 = p2;
1548
- }
1549
- if (counter % 2 === 0)
1550
- result = false;
1551
- }
1552
- return result;
1553
- }
1554
-
1555
- //
1556
- // Inherits the documentation of `intersects` in Shape
1557
- // TODO: Implement a check algorithm based on the real shape
1558
- intersects(r) {
1559
- return this.enclosing.intersects(r);
1560
- }
1561
-
1562
- //
1563
- // Inherits the documentation of `preparePath` in Shape
1564
- preparePath(ctx) {
1565
- // TODO: Implement filling paths
1566
- ctx.beginPath();
1567
- this.strokes.forEach(str => str.stroke(ctx));
1568
- return ctx;
1569
- }
1570
-
1571
- /**
1572
- * Gets a object with the basic attributes needed to rebuild this instance excluding functions,
1573
- * parent references, constants and also attributes retaining the default value.
1574
- * The resulting object is commonly usued to serialize elements in JSON format.
1575
- * @returns {object} - The resulting object, with minimal attrributes
1576
- */
1577
- getAttributes() {
1578
- return {
1579
- type: this.type,
1580
- strokes: this.strokes.map(s => s.getAttributes()).join('|'),
1581
- };
1582
- }
1583
-
1584
- /**
1585
- * Reads the properties of this Path from a data object
1586
- * @param {object} data - The data object to be parsed
1587
- * @returns {module:AWT.Path}
1588
- */
1589
- setAttributes(data) {
1590
- const strData = data.strokes.split('|');
1591
- const strokes = strData.map(s => {
1592
- const [type, points] = s.split(':');
1593
- return new PathStroke(type, points ? points.split(',') : []);
1594
- });
1595
- return this.setStrokes(strokes);
1596
- }
1597
- }
1598
-
1599
- Object.assign(Path.prototype, {
1600
- /**
1601
- * Shape type id
1602
- * @name module:AWT.Path#type
1603
- * @type {string} */
1604
- type: 'path',
1605
- /**
1606
- * The strokes forming this Path.
1607
- * @name module:AWT.Path#strokes
1608
- * @type {module:AWT.PathStroke[]} */
1609
- strokes: [],
1610
- /**
1611
- * The {@link module:AWT.Rectangle Rectangle} enclosing this Path (when drawing, this Rectangle don't include border width!)
1612
- * @name module:AWT.Path#enclosing
1613
- * @type {module:AWT.Rectangle} */
1614
- enclosing: new Rectangle(),
1615
- /**
1616
- * Set of vertexs of a polygon close to the real path of this shape
1617
- * @name module:AWT.Path#enclosingPoints
1618
- * @type {module:AWT.Point[]} */
1619
- enclosingPoints: [],
1620
- });
1621
-
1622
- /**
1623
- * PathStroke is the basic component of {@link module:AWT.Path} objects
1624
- */
1625
- class PathStroke {
1626
- /**
1627
- * PathStroke constructor
1628
- * @param {string} type - The type of stroke. Possible values are: `M` (move to), `L` (line to),
1629
- * `Q` (quadratic to), `B` (bezier to) and `X` (close path).
1630
- * @param {module:AWT.Point[]} points - The array of {@link module:AWT.Point} objects used in this Stroke.
1631
- */
1632
- constructor(type, points) {
1633
- this.type = type;
1634
- // Points are deep cloned, to avoid change the original values
1635
- if (points && points.length > 0) {
1636
- // Check if 'points' is an array of objects of type 'Point'
1637
- if (points[0] instanceof Point)
1638
- this.points = points.map(p => new Point(p));
1639
- // otherwise assume that 'points' contains just numbers
1640
- // to be readed in pairs of x and y co-ordinates
1641
- else {
1642
- this.points = [];
1643
- for (let i = 0; i < points.length; i += 2)
1644
- this.points.push(new Point(points[i], points[i + 1]));
1645
- }
1646
- }
1647
- }
1648
-
1649
- /**
1650
- * Calculates some of the points included in a quadratic Bézier curve
1651
- * The number of points being calculated is defined in Utils.settings.BEZIER_POINTS
1652
- * @see {@link https://en.wikipedia.org/wiki/B%C3%A9zier_curve}
1653
- * @see {@link https://www.jasondavies.com/animated-bezier/}
1654
- *
1655
- * @param {module:AWT.Point} p0 - Starting point of the quadratic Bézier curve
1656
- * @param {module:AWT.Point} p1 - Control point
1657
- * @param {module:AWT.Point} p2 - Ending point
1658
- * @param {number} [numPoints] - The number of intermediate points to calculate. When not defined,
1659
- * the value will be obtained from {@link module:Utils.settings.BEZIER_POINTS}.
1660
- * @returns {module:AWT.Point[]} - Array with some intermediate points from the resulting Bézier curve
1661
- */
1662
- static getQuadraticPoints(p0, p1, p2, numPoints) {
1663
- if (!numPoints)
1664
- numPoints = _Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .settings */ .W0.BEZIER_POINTS;
1665
- const
1666
- result = [],
1667
- pxa = new Point(),
1668
- pxb = new Point();
1669
- for (let i = 0; i < numPoints; i++) {
1670
- const n = (i + 1) / (numPoints + 1);
1671
- pxa.x = p0.x + (p1.x - p0.x) * n;
1672
- pxa.y = p0.y - (p0.y - p1.y) * n;
1673
- pxb.x = p1.x + (p2.x - p1.x) * n;
1674
- pxb.y = p1.y + (p2.y - p1.y) * n;
1675
- result.push(new Point(pxa.x + (pxb.x - pxa.x) * n, pxa.y - (pxa.y - pxb.y) * n));
1676
- }
1677
- return result;
1678
- }
1679
-
1680
- /**
1681
- * Calculates some of the points included in a cubic Bézier (curve with two control points)
1682
- * The number of points being calculated is defined in Utils.settings.BEZIER_POINTS
1683
- * @param {module:AWT.Point} p0 - Starting point of the cubic Bézier curve
1684
- * @param {module:AWT.Point} p1 - First control point
1685
- * @param {module:AWT.Point} p2 - Second control point
1686
- * @param {module:AWT.Point} p3 - Ending point
1687
- * @param {number} [numPoints] - The number of intermediate points to calculate. When not defined,
1688
- * the value will be obtained from {@link module:Utils.settings.BEZIER_POINTS}.
1689
- * @returns {module:AWT.Point[]} - Array with some intermediate points from the resulting Bézier curve
1690
- */
1691
- static getCubicPoints(p0, p1, p2, p3, numPoints) {
1692
- const result = [];
1693
- if (!numPoints)
1694
- numPoints = _Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .settings */ .W0.BEZIER_POINTS;
1695
- const pr = PathStroke.getQuadraticPoints(p0, p1, p2, numPoints);
1696
- const pq = PathStroke.getQuadraticPoints(p1, p2, p3, numPoints);
1697
- for (let i = 0; i < numPoints; i++) {
1698
- const n = (i + 1) / (numPoints + 1);
1699
- result.push(new Point(pr[i].x + (pq[i].x - pr[i].x) * n, pr[i].y - (pr[0].y - pq[0].y) * n));
1700
- }
1701
- return result;
1702
- }
1703
-
1704
- /**
1705
- * Clones this PathStroke
1706
- * @returns {module:AWT.PathStroke}
1707
- */
1708
- clone() {
1709
- // The constructors of PathStroke always make a deep copy of the `points` array
1710
- return new PathStroke(this.type, this.points);
1711
- }
1712
-
1713
- /**
1714
- * Increments or decrements by `delta` the x and y coordinates of all points
1715
- * @param {Point|Dimension} delta - The amount to add to the `x` and `y`
1716
- * coordinates of each point.
1717
- */
1718
- moveBy(delta) {
1719
- if (this.points)
1720
- this.points.forEach(pt => pt.moveBy(delta));
1721
- return this;
1722
- }
1723
-
1724
- /**
1725
- * Multiplies each point coordinates by the `x` and `y` (or `w` and `h`) values of the
1726
- * passed {@link module:AWT.Point} or {@link module:AWT.Dimension Dimension}.
1727
- * @param {Point|Dimension} delta
1728
- */
1729
- multBy(delta) {
1730
- if (this.points)
1731
- this.points.forEach(pt => pt.multBy(delta));
1732
- return this;
1733
- }
1734
-
1735
- /**
1736
- * Draws this PathStroke in the provided HTML canvas context
1737
- * @param {external:CanvasRenderingContext2D} ctx - The HTML canvas 2D rendering context
1738
- */
1739
- stroke(ctx) {
1740
- switch (this.type) {
1741
- case 'M':
1742
- ctx.moveTo(this.points[0].x, this.points[0].y);
1743
- break;
1744
- case 'L':
1745
- ctx.lineTo(this.points[0].x, this.points[0].y);
1746
- break;
1747
- case 'Q':
1748
- ctx.quadraticCurveTo(
1749
- this.points[0].x, this.points[0].y,
1750
- this.points[1].x, this.points[1].y);
1751
- break;
1752
- case 'B':
1753
- ctx.bezierCurveTo(
1754
- this.points[0].x, this.points[0].y,
1755
- this.points[1].x, this.points[1].y,
1756
- this.points[2].x, this.points[2].y);
1757
- break;
1758
- case 'X':
1759
- ctx.closePath();
1760
- break;
1761
- }
1762
- return ctx;
1763
- }
1764
-
1765
- /**
1766
- * Gets the set of points that will be included as a vertexs on the owner's shape
1767
- * enclosing polygon.
1768
- * @param {module:AWT.Point} from - The starting point for this stroke
1769
- * @returns {module:AWT.Point[]}
1770
- */
1771
- getEnclosingPoints(from) {
1772
- let result = [];
1773
- switch (this.type) {
1774
- case 'M':
1775
- case 'L':
1776
- result.push(this.points[0]);
1777
- break;
1778
- case 'Q':
1779
- result = PathStroke.getQuadraticPoints(from, this.points[0], this.points[1]);
1780
- result.push(this.points[1]);
1781
- break;
1782
- case 'B':
1783
- result = PathStroke.getCubicPoints(from, this.points[0], this.points[1], this.points[2]);
1784
- result.push(this.points[2]);
1785
- break;
1786
- }
1787
- return result;
1788
- }
1789
-
1790
- /**
1791
- * Gets a object with the basic attributes needed to rebuild this instance excluding functions,
1792
- * parent references, constants and also attributes retaining the default value.
1793
- * The resulting object is commonly usued to serialize elements in JSON format.
1794
- * @returns {object} - The resulting object, with minimal attrributes
1795
- */
1796
- getAttributes() {
1797
- return `${this.type}:${this.points ? this.points.map(p => `${(0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__.fx)(p.x)},${(0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__.fx)(p.y)}`).join(',') : ''}`;
1798
- }
1799
- }
1800
-
1801
- Object.assign(PathStroke.prototype, {
1802
- /**
1803
- * The Stroke type. Possible values are: `M` (move to), `L` (line to), `Q` (quadratic to),
1804
- * `B` (bezier to) and `X` (close path).
1805
- * @name module:AWT.PathStroke#type
1806
- * @type {string} */
1807
- type: 'X',
1808
- /**
1809
- * The array of points used by this stroke. Can be `null`.
1810
- * @name module:AWT.PathStroke#points
1811
- * @type {module:AWT.Point[]} */
1812
- points: null,
1813
- });
1814
-
1815
- /**
1816
- * This class encapsulates actions that can be linked to buttons, menus and other active objects
1817
- */
1818
- class Action {
1819
- /**
1820
- * Action constructor
1821
- * @param {string} name - The name of this Action
1822
- * @param {function} actionPerformed - The callback to be triggered by this Action
1823
- */
1824
- constructor(name, actionPerformed) {
1825
- this.name = name;
1826
- this.actionPerformed = actionPerformed;
1827
- this._statusListeners = [];
1828
- }
1829
-
1830
- /**
1831
- * Here is where subclasses must define the callback to be triggered when
1832
- * this Action object is called
1833
- * @param {module:AWT.Action} _thisAction - Pointer to this Action object
1834
- * @param {object} _event - The original action event that has originated this action
1835
- */
1836
- actionPerformed(_thisAction, _event) {
1837
- return this;
1838
- }
1839
-
1840
- /**
1841
- * This is the method to be passed to DOM event triggers
1842
- * @example
1843
- * const myFunc = () => { alert('Hello!') }
1844
- * const myAction = new Action('hello', myFunc)
1845
- * $( "#foo" ).bind( "click", myAction.processEvent)
1846
- * @param {object} event - The event object passed by the DOM event trigger
1847
- */
1848
- processEvent(event) {
1849
- return this.actionPerformed(this, event);
1850
- }
1851
-
1852
- /**
1853
- * Adds a status listener
1854
- * @param {function} listener - The callback method to be called when the status of this
1855
- * Action changes
1856
- */
1857
- addStatusListener(listener) {
1858
- this._statusListeners.push(listener);
1859
- }
1860
-
1861
- /**
1862
- * Removes a previously registered status listener
1863
- * @param {function} listener - The listener to be removed
1864
- */
1865
- removeStatusListener(listener) {
1866
- this._statusListeners = this._statusListeners.map(l => l !== listener);
1867
- }
1868
-
1869
- /**
1870
- * Enables or disables this action
1871
- * @param {boolean} enabled
1872
- */
1873
- setEnabled(enabled) {
1874
- this.enabled = enabled;
1875
- this._statusListeners.forEach(listener => listener.call(this, this));
1876
- return this;
1877
- }
1878
- }
1879
-
1880
- Object.assign(Action.prototype, {
1881
- /**
1882
- * The action's name
1883
- * @name module:AWT.Action#name
1884
- * @type {string} */
1885
- name: null,
1886
- /**
1887
- * An optional description
1888
- * @name module:AWT.Action#description
1889
- * @type {string} */
1890
- description: null,
1891
- /**
1892
- * Action status. `true` means enabled, `false` disabled
1893
- * @name module:AWT.Action#enabled
1894
- * @type {boolean} */
1895
- enabled: false,
1896
- /**
1897
- * Array of callback functions to be triggered when the `enabled` flag changes
1898
- * @name module:AWT.Action#_statusListeners
1899
- * @private
1900
- * @type {function[]} */
1901
- _statusListeners: null,
1902
- });
1903
-
1904
- /**
1905
- * This class provides a timer that will launch a function at specific intervals
1906
- */
1907
- class Timer {
1908
- /**
1909
- * Timer constructor
1910
- * @param {function} actionPerformed - The function to be triggered when the timer is enabled.
1911
- * @param {number} interval - The interval between action calls, specified in milliseconds.
1912
- * @param {boolean} [enabled=false] - Flag to indicate if the timer will be initially enabled.
1913
- */
1914
- constructor(actionPerformed, interval, enabled) {
1915
- this.actionPerformed = actionPerformed;
1916
- this.interval = interval;
1917
- this.setEnabled(enabled === true);
1918
- }
1919
-
1920
- /**
1921
- * Here is where subclasses must define the function to be performed when this timer ticks.
1922
- * @param {module:AWT.Timer} _thisTimer
1923
- */
1924
- actionPerformed(_thisTimer) {
1925
- return this;
1926
- }
1927
-
1928
- /**
1929
- * This is the method called by `window.setInterval`
1930
- * @param {external:Event} _event
1931
- */
1932
- processTimer(_event) {
1933
- this.ticks++;
1934
- if (!this.repeats)
1935
- this.stop();
1936
- return this.actionPerformed.call(this);
1937
- }
1938
-
1939
- /**
1940
- * Enables or disables this timer
1941
- * @param {boolean} enabled - Indicates if the timer should be enabled or disabled
1942
- * @param {boolean} [retainCounter=false] - When `true`, the ticks counter will not be cleared
1943
- */
1944
- setEnabled(enabled, retainCounter) {
1945
- if (!retainCounter)
1946
- this.ticks = 0;
1947
- if (enabled && this.timer !== null) {
1948
- // Timer already running
1949
- return;
1950
- }
1951
-
1952
- if (enabled) {
1953
- this.timer = window.setInterval(() => this.processTimer(null), this.interval);
1954
- } else {
1955
- if (this.timer !== null) {
1956
- window.clearInterval(this.timer);
1957
- this.timer = null;
1958
- }
1959
- }
1960
- return this;
1961
- }
1962
-
1963
- /**
1964
- * Checks if this timer is running
1965
- * @returns {boolean}
1966
- */
1967
- isRunning() {
1968
- return this.timer !== null;
1969
- }
1970
-
1971
- /**
1972
- * Starts this timer
1973
- * @param {boolean} [retainCounter=false] - When `true`, the ticks counter will not be cleared
1974
- */
1975
- start(retainCounter) {
1976
- return this.setEnabled(true, retainCounter);
1977
- }
1978
-
1979
- /**
1980
- * Stops this timer
1981
- * @param {boolean} [retainCounter=false] - When `true`, the ticks counter will not be cleared
1982
- */
1983
- stop(retainCounter) {
1984
- return this.setEnabled(false, retainCounter);
1985
- }
1986
- }
1987
-
1988
- Object.assign(Timer.prototype, {
1989
- /**
1990
- * The timer interval, in milliseconds
1991
- * @name module:AWT.Timer#interval
1992
- * @type {number} */
1993
- interval: 0,
1994
- /**
1995
- * The ticks counter
1996
- * @name module:AWT.Timer#ticks
1997
- * @type {number} */
1998
- ticks: 0,
1999
- /**
2000
- * The object returned by `window.setInterval`
2001
- * @name module:AWT.Timer#timer
2002
- * @type {object} */
2003
- timer: null,
2004
- /**
2005
- * When `true`, the timer should repeat until `stop` is called
2006
- * @name module:AWT.Timer#repeats
2007
- * @type {boolean} */
2008
- repeats: true,
2009
- });
2010
-
2011
- /**
2012
- * Logic object that takes care of an "invalidated" rectangle that will be repainted
2013
- * at the next update of a 2D object, usually an HTML Canvas.
2014
- * Container has the same constructor options as {@link module:AWT.Rectangle Rectangle}
2015
- * @extends module:AWT.Rectangle
2016
- */
2017
- class Container extends Rectangle {
2018
- /**
2019
- * Container constructor
2020
- * @param {Point|Rectangle|number|number[]} pos
2021
- * @param {Dimension|number} [dim]
2022
- * @param {number} [w]
2023
- * @param {number} [h]
2024
- */
2025
- constructor(pos, dim, w, h) {
2026
- super(pos, dim, w, h);
2027
- }
2028
-
2029
- /**
2030
- * Adds the provided rectangle to the invalidated area.
2031
- * @param {module:AWT.Rectangle} rect
2032
- */
2033
- invalidate(rect) {
2034
- if (rect) {
2035
- if (this.invalidatedRect === null)
2036
- this.invalidatedRect = rect.clone();
2037
- else
2038
- this.invalidatedRect.add(rect);
2039
- } else
2040
- this.invalidatedRect = null;
2041
- return this;
2042
- }
2043
-
2044
- /**
2045
- * Updates the invalidated area
2046
- */
2047
- update() {
2048
- this.updateContent(this.invalidatedRect);
2049
- this.invalidatedRect = null;
2050
- return this;
2051
- }
2052
-
2053
- /**
2054
- * Containers should implement this method to update its graphic contents. It should
2055
- * be called from {@link module:AWT.Container#update}
2056
- * @param {module:AWT.Shape} _dirtyRegion - Specifies the area to be updated. When `null`, it's the whole
2057
- * Container.
2058
- */
2059
- updateContent(_dirtyRegion) {
2060
- // To be overrided by subclasses. Here does nothing.
2061
- return this;
2062
- }
2063
- }
2064
-
2065
- Object.assign(Container.prototype, {
2066
- /**
2067
- * The currently "invalidated" area
2068
- * @name module:AWT.Container#invalidatedRect
2069
- * @type {module:AWT.Rectangle} */
2070
- invalidatedRect: null,
2071
- });
2072
-
2073
- /**
2074
- * This object contains utility clases for painting graphics and images,
2075
- * as found in the Java [Abstract Window Toolkit](http://docs.oracle.com/javase/7/docs/api/java/awt/package-summary.html)
2076
- *
2077
- * The objects defined here are: {@link module:AWT.Font Font}, {@link module:AWT.Gradient Gradient}, {@link module:AWT.Stroke Stroke},
2078
- * {@link module:AWT.Point Point}, {@link module:AWT.Dimension Dimension}, {@link module:AWT.Shape Shape}, {@link module:AWT.Rectangle Rectangle},
2079
- * {@link module:AWT.Ellipse Ellipse}, {@link module:AWT.Path Path}, {@link module:AWT.PathStroke PathStroke}, {@link module:AWT.Action Action},
2080
- * {@link module:AWT.Timer Timer} and {@link module:AWT.Container Container}.
2081
- */
2082
- /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
2083
- Font,
2084
- Gradient,
2085
- Stroke,
2086
- Point,
2087
- Dimension,
2088
- Shape,
2089
- Rectangle,
2090
- Ellipse,
2091
- Path,
2092
- PathStroke,
2093
- Action,
2094
- Timer,
2095
- Container
2096
- });
2097
-
2098
-
2099
- /***/ })
2100
-
2101
- };
2102
- ;
2103
- //# sourceMappingURL=7912.jclic-node.js.map