@woosh/meep-engine 2.39.18 → 2.39.19

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.
@@ -0,0 +1,420 @@
1
+ import { CanvasView } from "../../../view/elements/CanvasView.js";
2
+ import Vector3 from "../../../core/geom/Vector3.js";
3
+ import { compose_matrix4_array } from "../../../core/geom/3d/compose_matrix4_array.js";
4
+ import { mat4 } from "gl-matrix";
5
+ import { readPositionFromMouseEvent } from "../../../engine/input/devices/PointerDevice.js";
6
+ import Vector2, { v2_distance } from "../../../core/geom/Vector2.js";
7
+ import { Color } from "../../../core/color/Color.js";
8
+ import { inverseLerp } from "../../../core/math/inverseLerp.js";
9
+ import { clamp01 } from "../../../core/math/clamp01.js";
10
+ import { lerp } from "../../../core/math/lerp.js";
11
+ import Signal from "../../../core/events/signal/Signal.js";
12
+ import Quaternion from "../../../core/geom/Quaternion.js";
13
+ import { invertQuaternionOrientation } from "../../../engine/graphics/ecs/camera/InvertQuaternionOrientation.js";
14
+
15
+ const scratch_color = new Color();
16
+ const scratch_quat = new Quaternion();
17
+ const scratch_m4 = new Float32Array(16);
18
+
19
+ class DirectionStyle {
20
+ constructor() {
21
+ this.near = {
22
+ fill: new Color(1, 0, 0),
23
+ stroke_width: 0,
24
+ stroke_color: new Color(0, 0, 0)
25
+ };
26
+ this.far = {
27
+ fill: new Color(1, 0, 0),
28
+ stroke_width: 0,
29
+ stroke_color: new Color(0, 0, 0)
30
+ };
31
+ }
32
+
33
+ fromJSON({
34
+ near_fill = '#FF0000',
35
+ near_stroke_width = 0,
36
+ near_stroke_color = '#000000',
37
+ far_fill = '#FF0000',
38
+ far_stroke_width = 0,
39
+ far_stroke_color = '#000000'
40
+ }) {
41
+
42
+ this.near.fill.parse(near_fill);
43
+ this.near.stroke_width = near_stroke_width;
44
+ this.near.stroke_color.parse(near_stroke_color);
45
+
46
+ this.far.fill.parse(far_fill);
47
+ this.far.stroke_width = far_stroke_width;
48
+ this.far.stroke_color.parse(far_stroke_color);
49
+ }
50
+
51
+ static fromJSON(j) {
52
+ const r = new DirectionStyle();
53
+
54
+ r.fromJSON(j);
55
+
56
+ return r;
57
+ }
58
+ }
59
+
60
+
61
+ /**
62
+ * Modelled on https://github.com/jrj2211/three-orientation-gizmo/blob/master/src/OrientationGizmo.js
63
+ */
64
+ export class BlenderCameraOrientationGizmo extends CanvasView {
65
+ /**
66
+ *
67
+ * @param {Quaternion} quaternion
68
+ */
69
+ constructor(quaternion = null) {
70
+ super();
71
+
72
+ /**
73
+ *
74
+ * @type {Quaternion}
75
+ */
76
+ this.orientation = quaternion;
77
+
78
+ this.options = {
79
+ size: 100,
80
+ padding: 8,
81
+ bubbleSizePrimary: 10,
82
+ bubbleSizeSecondary: 8,
83
+ showSecondary: true,
84
+ lineWidth: 2,
85
+ fontSize: "11px",
86
+ fontFamily: "arial",
87
+ fontWeight: "bold",
88
+ fontColor: "rgba(0,0,0,0.8)",
89
+ fontYAdjust: 1,
90
+ selectionFontColor: "#FFFFFF",
91
+ invertOrientation: true,
92
+ axisStyles: {
93
+ px: DirectionStyle.fromJSON({
94
+ near_fill: "#FF3653",
95
+ far_fill: "#9D3B4A"
96
+ }),
97
+ py: DirectionStyle.fromJSON({
98
+ near_fill: "#8ADB00",
99
+ far_fill: "#648C23"
100
+ }),
101
+ pz: DirectionStyle.fromJSON({
102
+ near_fill: "#2C8FFF",
103
+ far_fill: "#36679D"
104
+ }),
105
+ nx: DirectionStyle.fromJSON({
106
+ near_stroke_color: "#FF3653",
107
+ near_stroke_width: 1,
108
+ near_fill: "#6E3D44",
109
+ far_stroke_color: "#9D3B4A",
110
+ far_stroke_width: 1,
111
+ far_fill: 'rgba(0,0,0,0)'
112
+ }),
113
+ ny: DirectionStyle.fromJSON({
114
+ near_stroke_color: "#8ADB00",
115
+ near_stroke_width: 1,
116
+ near_fill: "#526532",
117
+ far_stroke_color: "#648C23",
118
+ far_stroke_width: 1,
119
+ far_fill: 'rgba(0,0,0,0)'
120
+ }),
121
+ nz: DirectionStyle.fromJSON({
122
+ near_stroke_color: "#2C8FFF",
123
+ near_stroke_width: 1,
124
+ near_fill: "#3B536E",
125
+ far_stroke_color: "#36679D",
126
+ far_stroke_width: 1,
127
+ far_fill: 'rgba(0,0,0,0)'
128
+ })
129
+ }
130
+ };
131
+
132
+ // Generate list of axes
133
+ this.bubbles = [
134
+ {
135
+ axis: "x",
136
+ direction: new Vector3(1, 0, 0),
137
+ size: this.options.bubbleSizePrimary,
138
+ style: this.options.axisStyles.px,
139
+ line: this.options.lineWidth,
140
+ label: "X",
141
+ primary: true
142
+ },
143
+ {
144
+ axis: "y",
145
+ direction: new Vector3(0, 1, 0),
146
+ size: this.options.bubbleSizePrimary,
147
+ style: this.options.axisStyles.py,
148
+ line: this.options.lineWidth,
149
+ label: "Y",
150
+ primary: true
151
+ },
152
+ {
153
+ axis: "z",
154
+ direction: new Vector3(0, 0, 1),
155
+ size: this.options.bubbleSizePrimary,
156
+ style: this.options.axisStyles.pz,
157
+ line: this.options.lineWidth,
158
+ label: "Z",
159
+ primary: true
160
+ },
161
+ {
162
+ axis: "-x",
163
+ direction: new Vector3(-1, 0, 0),
164
+ size: this.options.bubbleSizeSecondary,
165
+ style: this.options.axisStyles.nx,
166
+ label: "-X",
167
+ labelHideUnselected: true,
168
+ primary: false
169
+ },
170
+ {
171
+ axis: "-y",
172
+ direction: new Vector3(0, -1, 0),
173
+ size: this.options.bubbleSizeSecondary,
174
+ style: this.options.axisStyles.ny,
175
+ label: "-Y",
176
+ labelHideUnselected: true,
177
+ primary: false
178
+ },
179
+ {
180
+ axis: "-z",
181
+ direction: new Vector3(0, 0, -1),
182
+ size: this.options.bubbleSizeSecondary,
183
+ style: this.options.axisStyles.nz,
184
+ label: "-Y",
185
+ labelHideUnselected: true,
186
+ primary: false
187
+ },
188
+ ];
189
+
190
+ /**
191
+ *
192
+ * @type {Vector3|null}
193
+ */
194
+ this.mouse = null;
195
+
196
+ this.center = new Vector3(this.options.size / 2, this.options.size / 2, 0);
197
+ this.selectedAxis = null;
198
+
199
+ this.size.setScalar(this.options.size);
200
+
201
+ this.onMouseMove = this.onMouseMove.bind(this);
202
+ this.onMouseOut = this.onMouseOut.bind(this);
203
+ this.onMouseClick = this.onMouseClick.bind(this);
204
+
205
+ /**
206
+ *
207
+ * Invoked when axis is clicked
208
+ * @type {Signal<string,Vector3>}
209
+ */
210
+ this.on.axisSelected = new Signal();
211
+ }
212
+
213
+ link() {
214
+ super.link();
215
+
216
+ const el = this.el;
217
+ el.addEventListener('mousemove', this.onMouseMove, false);
218
+ el.addEventListener('mouseout', this.onMouseOut, false);
219
+ el.addEventListener('click', this.onMouseClick, false);
220
+ }
221
+
222
+ unlink() {
223
+ const el = this.el;
224
+ el.removeEventListener('mousemove', this.onMouseMove, false);
225
+ el.removeEventListener('mouseout', this.onMouseOut, false);
226
+ el.removeEventListener('click', this.onMouseClick, false);
227
+
228
+ super.unlink();
229
+ }
230
+
231
+ /**
232
+ *
233
+ * @param {MouseEvent} evt
234
+ */
235
+ onMouseMove(evt) {
236
+ const v2 = new Vector2();
237
+ readPositionFromMouseEvent(v2, evt);
238
+
239
+ this.mouse = new Vector3(v2.x, v2.y, 0);
240
+ }
241
+
242
+ /**
243
+ *
244
+ * @param {MouseEvent} evt
245
+ */
246
+ onMouseOut(evt) {
247
+ this.mouse = null;
248
+ }
249
+
250
+ /**
251
+ *
252
+ * @param {MouseEvent} evt
253
+ */
254
+ onMouseClick(evt) {
255
+ if (this.selectedAxis !== null) {
256
+ this.on.axisSelected.send2(
257
+ this.selectedAxis.axis,
258
+ this.selectedAxis.direction.clone()
259
+ );
260
+ }
261
+ }
262
+
263
+ drawCircle(p, radius = 10, fill_color = "#FF0000", stroke_width = 0, stroke_color = "#FFFFFF") {
264
+ const ctx = this.context2d;
265
+
266
+ ctx.beginPath();
267
+ ctx.arc(p.x, p.y, radius, 0, 2 * Math.PI, false);
268
+ ctx.fillStyle = fill_color;
269
+ ctx.fill();
270
+
271
+ if (stroke_width > 0) {
272
+ ctx.lineWidth = stroke_width;
273
+ ctx.strokeStyle = stroke_color;
274
+ ctx.stroke();
275
+ }
276
+
277
+ ctx.closePath();
278
+ }
279
+
280
+ drawLine(p1, p2, width = 1, color = "#FF0000") {
281
+ const ctx = this.context2d;
282
+
283
+ ctx.beginPath();
284
+ ctx.moveTo(p1.x, p1.y);
285
+ ctx.lineTo(p2.x, p2.y);
286
+ ctx.lineWidth = width;
287
+ ctx.strokeStyle = color;
288
+ ctx.stroke();
289
+ ctx.closePath();
290
+ }
291
+
292
+ update() {
293
+ this.clear();
294
+
295
+ // Calculate the rotation matrix from the camera
296
+ const rotation_matrix = scratch_m4;
297
+ let rotation = this.orientation;
298
+
299
+ if (rotation === null) {
300
+ // not connected
301
+ return;
302
+ }
303
+
304
+ if (this.options.invertOrientation) {
305
+ const q = scratch_quat;
306
+
307
+ invertQuaternionOrientation(q, rotation);
308
+
309
+ rotation = q;
310
+ }
311
+
312
+ compose_matrix4_array(rotation_matrix, Vector3.zero, rotation, Vector3.one);
313
+ mat4.invert(rotation_matrix, rotation_matrix);
314
+
315
+ for (let bubble of this.bubbles) {
316
+ const direction = bubble.direction.clone();
317
+ direction.applyMatrix4(rotation_matrix);
318
+
319
+ bubble.position = this.getBubblePosition(direction);
320
+ }
321
+
322
+ // Generate a list of layers to draw
323
+ const layers = [];
324
+ for (let axis in this.bubbles) {
325
+ // Check if the name starts with a negative and dont add it to the layer list if secondary axis is turned off
326
+ if (this.options.showSecondary === true || axis[0] !== "-") {
327
+ layers.push(this.bubbles[axis]);
328
+ }
329
+ }
330
+
331
+ // Sort the layers where the +Z position is last so its drawn on top of anything below it
332
+ layers.sort((a, b) => (a.position.z > b.position.z) ? 1 : -1);
333
+
334
+ // If the mouse is over the gizmo, find the closest axis and highlight it
335
+ this.selectedAxis = null;
336
+
337
+ if (this.mouse) {
338
+ let closestDist = Infinity;
339
+ let closestZ = -Infinity;
340
+
341
+ // Loop through each layer
342
+ for (let bubble of layers) {
343
+ const distance = v2_distance(this.mouse.x, this.mouse.y, bubble.position.x, bubble.position.y);
344
+
345
+ // Only select the axis if its closer to the mouse than the previous or if its within its bubble circle
346
+ if (
347
+ distance < closestDist
348
+ && closestZ < bubble.position.z
349
+ && distance <= bubble.size
350
+ ) {
351
+
352
+ closestDist = distance;
353
+ closestZ = bubble.position.z;
354
+ this.selectedAxis = bubble;
355
+
356
+ }
357
+ }
358
+ }
359
+
360
+ // Draw the layers
361
+ this.drawLayers(layers);
362
+ }
363
+
364
+ /**
365
+ *
366
+ * @param {{style:DirectionStyle, position:Vector3, size:number,line:boolean, label?:string,labelHideUnselected?:boolean}[]} layers
367
+ */
368
+ drawLayers(layers) {
369
+ // For each layer, draw the bubble
370
+ for (let bubble of layers) {
371
+
372
+ // Find the color
373
+ const is_selected = this.selectedAxis === bubble;
374
+
375
+ const closeness = clamp01(inverseLerp(-1, 0.8, bubble.position.z));
376
+
377
+ const style = bubble.style;
378
+
379
+ scratch_color.lerpColors(style.far.fill, style.near.fill, closeness);
380
+ const fill_color = scratch_color.toCssRGBAString();
381
+
382
+ scratch_color.lerpColors(style.far.stroke_color, style.near.stroke_color, closeness);
383
+ const stroke_color = scratch_color.toCssRGBAString();
384
+
385
+ const stroke_width = lerp(style.far.stroke_width, style.near.stroke_width, closeness);
386
+
387
+ // Draw the circle for the bubbble
388
+ this.drawCircle(bubble.position, bubble.size, fill_color, stroke_width, stroke_color);
389
+
390
+ // Draw the line that connects it to the center if enabled
391
+ if (bubble.line) {
392
+ this.drawLine(this.center, bubble.position, bubble.line, fill_color);
393
+ }
394
+
395
+ // Write the axis label (X,Y,Z) if provided
396
+ if (bubble.label && (is_selected || (bubble.labelHideUnselected !== true))) {
397
+ const ctx = this.context2d;
398
+
399
+ ctx.font = [this.options.fontWeight, this.options.fontSize, this.options.fontFamily].join(" ");
400
+ ctx.fillStyle = is_selected ? this.options.selectionFontColor : this.options.fontColor;
401
+ ctx.textBaseline = 'middle';
402
+ ctx.textAlign = 'center';
403
+ ctx.fillText(bubble.label, bubble.position.x, bubble.position.y + this.options.fontYAdjust);
404
+ }
405
+ }
406
+ }
407
+
408
+ /**
409
+ *
410
+ * @param {Vector3} position
411
+ * @returns {Vector3}
412
+ */
413
+ getBubblePosition(position) {
414
+ return new Vector3(
415
+ (position.x * (this.center.x - (this.options.bubbleSizePrimary / 2) - this.options.padding)) + this.center.x,
416
+ this.center.y - (position.y * (this.center.y - (this.options.bubbleSizePrimary / 2) - this.options.padding)),
417
+ position.z
418
+ );
419
+ }
420
+ }
@@ -3,7 +3,7 @@ import {EntityComponentDataset} from "../../../engine/ecs/EntityComponentDataset
3
3
  import {EntityNode} from "../../../engine/ecs/parent/EntityNode";
4
4
 
5
5
  export class TransformControls extends EntityNode {
6
- constructor(camera: PerspectiveCamera | OrthographicCamera, domElement: HTMLElement)
6
+ constructor(camera: PerspectiveCamera | OrthographicCamera, domElement: HTMLElement, autoUpdate?: boolean)
7
7
 
8
8
  build(ecd: EntityComponentDataset): void
9
9
 
@@ -12,4 +12,9 @@ export class TransformControls extends EntityNode {
12
12
  attach(entity: number): void
13
13
 
14
14
  detach(): void
15
+
16
+ /**
17
+ * Can be triggered manually if `autoUpdate` was not set in the constructor
18
+ */
19
+ update(): void
15
20
  }
@@ -428,8 +428,8 @@ class EditorView extends View {
428
428
  this.toolBar.size.set(this.gameView.size.x, 36);
429
429
  this.toolBar.position.set(this.gameView.position.x + 5, this.gameView.position.y + this.gameView.size.y - (this.toolBar.size.y + 5));
430
430
 
431
- this.processBar.size.set(this.gameView.size.x, 36);
432
- this.processBar.position.set(this.toolBar.position.x, 5);
431
+ // this.processBar.size.set(this.gameView.size.x, 36);
432
+ // this.processBar.position.set(this.toolBar.position.x, 5);
433
433
 
434
434
  this.meshLibraryView.position.set(this.gameView.position.x + this.gameView.size.x - (this.meshLibraryView.size.x + 5), 5);
435
435
  }
@@ -12,6 +12,7 @@ import { computePointDistanceToPlane } from "../../../../core/geom/Plane.js";
12
12
  import { unprojectPoint } from "./unprojectPoint.js";
13
13
  import Vector3 from "../../../../core/geom/Vector3.js";
14
14
  import { frustum_from_camera } from "./frustum_from_camera.js";
15
+ import { invertQuaternionOrientation } from "./InvertQuaternionOrientation.js";
15
16
 
16
17
  /**
17
18
  *
@@ -75,6 +76,15 @@ export class Camera {
75
76
  this.__clip_near = 0.1;
76
77
  }
77
78
 
79
+ /**
80
+ *
81
+ * @param {Quaternion} output
82
+ * @param {Quaternion} input
83
+ */
84
+ getReciprocalRotation(output, input) {
85
+ invertQuaternionOrientation(output, input);
86
+ }
87
+
78
88
  get clip_far() {
79
89
  return this.__clip_far;
80
90
  }
@@ -200,7 +210,7 @@ export class Camera {
200
210
  source.copy(scratch_v3_1);
201
211
  direction.copy(scratch_v3_0);
202
212
 
203
- } else {
213
+ } else {
204
214
  throw new Error('Unsupported camera type');
205
215
  }
206
216
  }
@@ -6,20 +6,15 @@
6
6
  import { System } from '../../../ecs/System.js';
7
7
  import { Camera } from './Camera.js';
8
8
  import { Transform } from '../../../ecs/transform/Transform.js';
9
- import { Frustum as ThreeFrustum, Matrix4, } from 'three';
9
+ import { Frustum as ThreeFrustum, } from 'three';
10
10
  import { assert } from "../../../../core/assert.js";
11
11
  import { SignalBinding } from "../../../../core/events/signal/SignalBinding.js";
12
- import Vector3 from "../../../../core/geom/Vector3.js";
13
12
  import { set_camera_aspect_ratio } from "./set_camera_aspect_ratio.js";
14
13
  import { build_three_camera_object } from "./build_three_camera_object.js";
15
14
  import { update_camera_transform } from "./update_camera_transform.js";
16
15
  import { auto_set_camera_clipping_planes } from "./auto_set_camera_clipping_planes.js";
17
16
  import { frustum_from_camera } from "./frustum_from_camera.js";
18
-
19
- const m4_scratch = new Matrix4();
20
-
21
- const v3_scratch_0 = new Vector3();
22
- const v3_scratch_1 = new Vector3();
17
+ import { invertQuaternionOrientation } from "./InvertQuaternionOrientation.js";
23
18
 
24
19
  export class CameraSystem extends System {
25
20
  /**
@@ -114,22 +109,9 @@ export class CameraSystem extends System {
114
109
  See: https://github.com/mrdoob/three.js/blob/412b99a7f26e117ea97f40eb53d010ab81aa3279/src/core/Object3D.js#L282
115
110
  */
116
111
 
117
- // get forward and up vectors
118
-
119
-
120
- const forward = v3_scratch_0;
121
- const up = v3_scratch_1;
122
-
123
- forward.copy(Vector3.forward);
124
- up.copy(Vector3.up);
125
-
126
- forward.applyQuaternion(rotation);
127
- up.applyQuaternion(rotation);
128
-
129
- m4_scratch.lookAt(Vector3.zero, forward, up);
112
+ invertQuaternionOrientation(camera.object.quaternion, rotation);
130
113
 
131
- camera.object.rotation.setFromRotationMatrix(m4_scratch);
132
- camera.object.quaternion.setFromRotationMatrix(m4_scratch);
114
+ camera.object.rotation.setFromQuaternion(camera.object.quaternion);
133
115
 
134
116
  // rotation.__setThreeEuler(camera.object.rotation); // seems unnecessary, based on Object3D.lookAt implementation
135
117
  // camera.object.quaternion.set(rotation.x, rotation.y, rotation.z, rotation.w);
@@ -0,0 +1,26 @@
1
+ import Vector3 from "../../../../core/geom/Vector3.js";
2
+ import { Matrix4 } from "three";
3
+
4
+ const m4_scratch = new Matrix4();
5
+ const v3_scratch_0 = new Vector3();
6
+ const v3_scratch_1 = new Vector3();
7
+
8
+ /**
9
+ *
10
+ * @param {Quaternion} output
11
+ * @param {Quaternion} input
12
+ */
13
+ export function invertQuaternionOrientation(output, input) {
14
+ const forward = v3_scratch_0;
15
+ const up = v3_scratch_1;
16
+
17
+ forward.copy(Vector3.forward);
18
+ up.copy(Vector3.up);
19
+
20
+ forward.applyQuaternion(input);
21
+ up.applyQuaternion(input);
22
+
23
+ m4_scratch.lookAt(Vector3.zero, forward, up);
24
+
25
+ output.setFromRotationMatrix(m4_scratch);
26
+ }
@@ -306,7 +306,7 @@ function observeDrag(up, down, move, dragStart, dragEnd, drag) {
306
306
  * @param {MouseEvent} event
307
307
  * @param {Element} source
308
308
  */
309
- function readPositionFromMouseEvent(result, event, source = event.target) {
309
+ export function readPositionFromMouseEvent(result, event, source = event.target) {
310
310
  let x = event.clientX;
311
311
  let y = event.clientY;
312
312
 
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "productName": "Meep",
6
6
  "description": "production-ready JavaScript game engine based on Entity Component System Architecture",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.39.18",
8
+ "version": "2.39.19",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",
package/view/SVG.js CHANGED
@@ -2,6 +2,7 @@
2
2
  * Created by Alex on 13/12/2016.
3
3
  */
4
4
 
5
+ export const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
5
6
 
6
7
  /**
7
8
  *
@@ -111,7 +112,7 @@ function svgArc2(r0, r1, a0, b0, a1, b1) {
111
112
  * @returns {Element}
112
113
  */
113
114
  function createSVGElement(tag) {
114
- return document.createElementNS("http://www.w3.org/2000/svg", tag);
115
+ return document.createElementNS(SVG_NAMESPACE, tag);
115
116
  }
116
117
 
117
118
  export default {
package/view/View.d.ts CHANGED
@@ -1,4 +1,10 @@
1
1
  import Vector2 from "../core/geom/Vector2";
2
+ import Signal from "../core/events/signal/Signal";
3
+
4
+ export interface IViewSignals {
5
+ readonly linked: Signal
6
+ readonly unlinked: Signal
7
+ }
2
8
 
3
9
  export default class View<T extends Element = HTMLElement> {
4
10
  size: Vector2
@@ -6,6 +12,8 @@ export default class View<T extends Element = HTMLElement> {
6
12
 
7
13
  el: T
8
14
 
15
+ readonly on: IViewSignals
16
+
9
17
  public link(): void
10
18
 
11
19
  public unlink(): void
@@ -3,32 +3,38 @@
3
3
  */
4
4
 
5
5
  import View from "../View.js";
6
- import dom from "../DOM.js";
7
6
 
8
7
  class EmptyView extends View {
9
8
  /**
10
- *
11
- * @param options
9
+ * @param {string[]} [classList]
10
+ * @param {Element} [el]
11
+ * @param {string} [tag]
12
+ * @param {string} [tagNamespace]
13
+ * @param {Object<string>} [css]
14
+ * @param {Object<string>} [attr]
12
15
  * @extends {View}
13
16
  * @constructor
14
17
  */
15
- constructor({ classList = [], tag = 'div', css } = {}) {
18
+ constructor({ classList = [], el, tag = 'div', tagNamespace = undefined, css, attr } = {}) {
16
19
  super();
17
20
 
18
- this.dRoot = dom(tag);
19
-
20
- const elClassList = this.dRoot.el.classList;
21
-
22
- for (let i = 0, l = classList.length; i < l; i++) {
23
- const className = classList[i];
24
- elClassList.add(className);
21
+ if (el !== undefined) {
22
+ this.el = el;
23
+ } else if (tagNamespace !== undefined) {
24
+ this.el = document.createElementNS(tagNamespace, tag);
25
+ } else {
26
+ this.el = document.createElement(tag);
25
27
  }
26
28
 
27
- this.el = this.dRoot.el;
29
+ this.addClasses(classList);
28
30
 
29
31
  if (css !== undefined) {
30
32
  this.css(css);
31
33
  }
34
+
35
+ if (attr !== undefined) {
36
+ this.attr(attr);
37
+ }
32
38
  }
33
39
 
34
40
  /**
@@ -17,6 +17,15 @@ function makeTextAbsolute(value, max, process) {
17
17
  }
18
18
 
19
19
  class ProgressBarView extends View {
20
+ /**
21
+ *
22
+ * @param {number[]|BoundedValue} model
23
+ * @param classList
24
+ * @param displayLabel
25
+ * @param displayLabelType
26
+ * @param displayTipMarker
27
+ * @param process
28
+ */
20
29
  constructor(model, {
21
30
  classList = [],
22
31
  displayLabel = false,