muigui 0.0.1 → 0.0.3

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 (72) hide show
  1. package/README.md +72 -7
  2. package/package.json +10 -6
  3. package/src/controllers/Button.js +34 -0
  4. package/src/controllers/Canvas.js +17 -0
  5. package/src/controllers/Checkbox.js +11 -0
  6. package/src/controllers/Color.js +31 -0
  7. package/src/controllers/ColorChooser.js +12 -0
  8. package/src/controllers/Container.js +58 -0
  9. package/src/controllers/Controller.js +138 -0
  10. package/src/controllers/Direction.js +23 -0
  11. package/src/controllers/Divider.js +9 -0
  12. package/src/controllers/Folder.js +37 -0
  13. package/src/controllers/Label.js +14 -0
  14. package/src/controllers/LabelController.js +32 -0
  15. package/src/controllers/PopDownController.js +84 -0
  16. package/src/controllers/RadioGrid.js +17 -0
  17. package/src/controllers/Range.js +11 -0
  18. package/src/controllers/Select.js +14 -0
  19. package/src/controllers/Slider.js +12 -0
  20. package/src/controllers/TabHolder.js +36 -0
  21. package/src/controllers/Text.js +10 -0
  22. package/src/controllers/TextNumber.js +18 -0
  23. package/src/controllers/ValueController.js +107 -0
  24. package/src/controllers/Vec2.js +50 -0
  25. package/src/controllers/create-controller.js +49 -0
  26. package/src/layout/Column.js +7 -0
  27. package/src/layout/Frame.js +11 -0
  28. package/src/layout/Grid.js +7 -0
  29. package/src/layout/Layout.js +47 -0
  30. package/src/layout/Row.js +7 -0
  31. package/src/libs/assert.js +5 -0
  32. package/src/libs/color-utils.js +406 -0
  33. package/src/libs/conversions.js +14 -0
  34. package/src/libs/css-utils.js +3 -0
  35. package/src/libs/elem.js +8 -3
  36. package/src/libs/emitter.js +68 -0
  37. package/src/libs/iterable-array.js +57 -0
  38. package/src/libs/key-values.js +25 -0
  39. package/src/libs/keyboard.js +32 -0
  40. package/src/libs/resize-helpers.js +22 -0
  41. package/src/libs/svg.js +33 -0
  42. package/src/libs/taskrunner.js +56 -0
  43. package/src/libs/touch.js +50 -0
  44. package/src/libs/utils.js +38 -2
  45. package/src/libs/wheel.js +10 -0
  46. package/src/muigui.js +79 -19
  47. package/src/styles/muigui.css.js +641 -0
  48. package/src/umd.js +3 -0
  49. package/src/views/CheckboxView.js +21 -0
  50. package/src/views/ColorChooserView.js +124 -0
  51. package/src/views/ColorView.js +50 -0
  52. package/src/views/DirectionView.js +127 -0
  53. package/src/views/EditView.js +100 -0
  54. package/src/views/ElementView.js +8 -0
  55. package/src/views/GridView.js +15 -0
  56. package/src/views/NumberView.js +67 -0
  57. package/src/views/RadioGridView.js +46 -0
  58. package/src/views/RangeView.js +73 -0
  59. package/src/views/SelectView.js +23 -0
  60. package/src/views/SliderView.js +194 -0
  61. package/src/views/TextView.js +49 -0
  62. package/src/views/ValueView.js +11 -0
  63. package/src/views/Vec2View.js +51 -0
  64. package/src/views/View.js +56 -0
  65. package/src/widgets/checkbox.js +0 -0
  66. package/src/widgets/divider.js +0 -0
  67. package/src/widgets/menu.js +0 -0
  68. package/src/widgets/radio.js +0 -0
  69. package/src/widgets/select.js +0 -1
  70. package/src/widgets/slider.js +0 -41
  71. package/src/widgets/text.js +0 -0
  72. package/src/widgets/widget.js +0 -51
@@ -0,0 +1,56 @@
1
+ import { removeArrayElem } from './utils.js';
2
+
3
+ const tasks = [];
4
+ const tasksToRemove = new Set();
5
+
6
+ let requestId;
7
+ let processing;
8
+
9
+ function removeTasks() {
10
+ if (!tasksToRemove.size) {
11
+ return;
12
+ }
13
+
14
+ if (processing) {
15
+ queueProcessing();
16
+ return;
17
+ }
18
+
19
+ tasksToRemove.forEach(task => {
20
+ removeArrayElem(tasks, task);
21
+ });
22
+ tasksToRemove.clear();
23
+ }
24
+
25
+ function processTasks() {
26
+ requestId = undefined;
27
+ processing = true;
28
+ for (const task of tasks) {
29
+ if (!tasksToRemove.has(task)) {
30
+ task();
31
+ }
32
+ }
33
+ processing = false;
34
+ removeTasks();
35
+ queueProcessing();
36
+ }
37
+
38
+ function queueProcessing() {
39
+ if (!requestId && tasks.length) {
40
+ requestId = requestAnimationFrame(processTasks);
41
+ }
42
+ }
43
+
44
+ export function addTask(fn) {
45
+ tasks.push(fn);
46
+ queueProcessing();
47
+ }
48
+
49
+ export function removeTask(fn) {
50
+ tasksToRemove.set(fn);
51
+
52
+ const ndx = tasks.indexOf(fn);
53
+ if (ndx >= 0) {
54
+ tasks.splice(ndx, 1);
55
+ }
56
+ }
@@ -0,0 +1,50 @@
1
+ function noop() {
2
+ }
3
+
4
+ export function computeRelativePosition(elem, event, start) {
5
+ const rect = elem.getBoundingClientRect();
6
+ const x = event.clientX - rect.left;
7
+ const y = event.clientY - rect.top;
8
+ const nx = x / rect.width;
9
+ const ny = y / rect.height;
10
+ start = start || [x, y];
11
+ const dx = x - start[0];
12
+ const dy = y - start[1];
13
+ const ndx = dx / rect.width;
14
+ const ndy = dy / rect.width;
15
+ return {x, y, nx, ny, dx, dy, ndx, ndy};
16
+ }
17
+
18
+ export function addTouchEvents(elem, {onDown = noop, onMove = noop, onUp = noop}) {
19
+ let start;
20
+ const mouseMove = function(event) {
21
+ const e = {
22
+ type: 'move',
23
+ ...computeRelativePosition(elem, event, start),
24
+ };
25
+ onMove(e);
26
+ };
27
+
28
+ const mouseUp = function() {
29
+ window.removeEventListener('mousemove', mouseMove);
30
+ window.removeEventListener('mouseup', mouseUp);
31
+ onUp('up');
32
+ };
33
+
34
+ const mouseDown = function(event) {
35
+ window.addEventListener('mousemove', mouseMove);
36
+ window.addEventListener('mouseup', mouseUp);
37
+ const rel = computeRelativePosition(elem, event);
38
+ start = [rel.x, rel.y];
39
+ onDown({
40
+ type: 'down',
41
+ ...rel,
42
+ });
43
+ };
44
+
45
+ elem.addEventListener('mousedown', mouseDown);
46
+
47
+ return function() {
48
+ elem.removeEventListener('mousedown', mouseDown);
49
+ };
50
+ }
package/src/libs/utils.js CHANGED
@@ -1,4 +1,4 @@
1
- export function removeElem(array, value) {
1
+ export function removeArrayElem(array, value) {
2
2
  const ndx = array.indexOf(value);
3
3
  if (ndx) {
4
4
  array.splice(ndx, 1);
@@ -8,7 +8,7 @@ export function removeElem(array, value) {
8
8
 
9
9
  /**
10
10
  * Converts an camelCase or snake_case id to "camel case" or "snake case"
11
- * @param {string} id
11
+ * @param {string} id
12
12
  */
13
13
  const underscoreRE = /_/g;
14
14
  const upperLowerRE = /([A-Z])([a-z])/g;
@@ -17,3 +17,39 @@ export function idToLabel(id) {
17
17
  .replace(upperLowerRE, (m, m1, m2) => `${m1.toLowerCase()} ${m2}`);
18
18
  }
19
19
 
20
+ export function clamp(v, min, max) {
21
+ return Math.max(min, Math.min(max, v));
22
+ }
23
+
24
+ export const isTypedArray = typeof SharedArrayBuffer !== 'undefined'
25
+ ? function isArrayBufferOrSharedArrayBuffer(a) {
26
+ return a && a.buffer && (a.buffer instanceof ArrayBuffer || a.buffer instanceof SharedArrayBuffer);
27
+ }
28
+ : function isArrayBuffer(a) {
29
+ return a && a.buffer && a.buffer instanceof ArrayBuffer;
30
+ };
31
+
32
+ export const isArrayOrTypedArray = v => Array.isArray(v) || isTypedArray(v);
33
+
34
+ // Yea, I know this should be `Math.round(v / step) * step
35
+ // but try step = 0.1, newV = 19.95
36
+ //
37
+ // I get
38
+ // Math.round(19.95 / 0.1) * 0.1
39
+ // 19.900000000000002
40
+ // vs
41
+ // Math.round(19.95 / 0.1) / (1 / 0.1)
42
+ // 19.9
43
+ //
44
+ export const stepify = (v, from, step) => Math.round(from(v) / step) / (1 / step);
45
+
46
+ export const euclideanModulo = (v, n) => ((v % n) + n) % n;
47
+ export const lerp = (a, b, t) => a + (b - a) * t;
48
+ export function copyExistingProperties(dst, src) {
49
+ for (const key in src) {
50
+ if (key in dst) {
51
+ dst[key] = src[key];
52
+ }
53
+ }
54
+ return dst;
55
+ }
@@ -0,0 +1,10 @@
1
+ export function createWheelHelper() {
2
+ let wheelAccum = 0;
3
+ return function(e, step, wheelScale = 5) {
4
+ wheelAccum -= e.deltaY * step / wheelScale;
5
+ const wheelSteps = Math.floor(Math.abs(wheelAccum) / step) * Math.sign(wheelAccum);
6
+ const delta = wheelSteps * step;
7
+ wheelAccum -= delta;
8
+ return delta;
9
+ };
10
+ }
package/src/muigui.js CHANGED
@@ -1,26 +1,86 @@
1
- import { createElem } from './libs/elem.js';
2
- import Slider from './widgets/slider.js';
3
- import Widget from './widgets/widget.js';
1
+ import css from './styles/muigui.css.js';
2
+ import {createElem} from './libs/elem.js';
3
+ import {createController} from './controllers/create-controller.js';
4
+ import Canvas from './controllers/Canvas.js';
5
+ import Color from './controllers/Color.js';
6
+ import Divider from './controllers/Divider.js';
7
+ import Folder from './controllers/Folder.js';
8
+ import Label from './controllers/Label.js';
9
+ import Controller from './controllers/Controller.js';
4
10
 
5
- export function createWidget(object, property, ...args) {
6
- const t = typeof object[property];
7
- switch (t) {
8
- case 'number':
9
- return new Slider(object, property, ...args);
11
+ import Column from './layout/Column.js';
12
+ import Frame from './layout/Frame.js';
13
+ import Grid from './layout/Grid.js';
14
+ import Row from './layout/Row.js';
15
+
16
+ export {
17
+ Column,
18
+ Frame,
19
+ Grid,
20
+ Row,
21
+ };
22
+
23
+ let stylesInjected = false;
24
+ const styleElem = createElem('style');
25
+
26
+ export class GUIFolder extends Folder {
27
+ add(object, property, ...args) {
28
+ const controller = object instanceof Controller
29
+ ? object
30
+ : createController(object, property, ...args);
31
+ return this.addController(controller);
32
+ }
33
+ addCanvas(name) {
34
+ return this.addController(new Canvas(name));
35
+ }
36
+ addColor(object, property, ...args) {
37
+ return this.addController(new Color(object, property, ...args));
38
+ }
39
+ addDivider() {
40
+ return this.addController(new Divider());
41
+ }
42
+ addFolder(name) {
43
+ return this.addController(new GUIFolder(name));
44
+ }
45
+ addLabel(text) {
46
+ return this.addController(new Label(text));
10
47
  }
11
48
  }
12
49
 
13
- export class GUI extends Widget {
14
- constructor() {
15
- super({}, 'Controls', 'muigui-root');
16
- document.body.appendChild(this.elem);
17
- this._widgetsElem = createElem('div');
18
- this.elem.appendChild(this._widgetsElem);
19
- }
20
- add(object, property, ...args) {
21
- const widget = createWidget(object, property, ...args);
22
- this._widgetsElem.appendChild(widget.elem);
23
- return this;
50
+ export class GUI extends GUIFolder {
51
+ constructor(options = {}) {
52
+ super('Controls', 'muigui-root');
53
+ if (options instanceof HTMLElement) {
54
+ options = {parent: options};
55
+ }
56
+ const {
57
+ autoPlace = true,
58
+ width,
59
+ title = 'Controls',
60
+ injectStyles = true,
61
+ } = options;
62
+ let {
63
+ parent,
64
+ } = options;
65
+ if (injectStyles && !stylesInjected) {
66
+ stylesInjected = true;
67
+ (document.head || document.documentElement).appendChild(styleElem);
68
+ styleElem.textContent = css;
69
+ }
70
+ if (width) {
71
+ this.domElement.style.width = /^\d+$/.test(width) ? `${width}px` : width;
72
+ }
73
+ if (parent === undefined && autoPlace) {
74
+ parent = document.body;
75
+ this.domElement.classList.add('muigui-auto-place');
76
+ }
77
+ if (parent) {
78
+ parent.appendChild(this.domElement);
79
+ }
80
+ if (title) {
81
+ this.title(title);
82
+ }
83
+ this.domElement.classList.add('muigui');
24
84
  }
25
85
  }
26
86