lexgui 0.7.15 → 8.1.0

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 (134) hide show
  1. package/LICENSE +201 -21
  2. package/README.md +14 -5
  3. package/build/components/AlertDialog.d.ts +7 -0
  4. package/build/components/ArrayInput.d.ts +9 -0
  5. package/build/components/BaseComponent.d.ts +73 -0
  6. package/build/components/Button.d.ts +14 -0
  7. package/build/components/Calendar.d.ts +41 -0
  8. package/build/components/CalendarRange.d.ts +16 -0
  9. package/build/components/CanvasCurve.d.ts +10 -0
  10. package/build/components/CanvasDial.d.ts +11 -0
  11. package/build/components/CanvasMap2D.d.ts +61 -0
  12. package/build/components/Card.d.ts +8 -0
  13. package/build/components/Checkbox.d.ts +8 -0
  14. package/build/components/Color.d.ts +20 -0
  15. package/build/components/ColorInput.d.ts +13 -0
  16. package/build/components/ColorPicker.d.ts +29 -0
  17. package/build/components/ComboButtons.d.ts +8 -0
  18. package/build/components/ContextMenu.d.ts +16 -0
  19. package/build/components/Counter.d.ts +9 -0
  20. package/build/components/Curve.d.ts +10 -0
  21. package/build/components/DatePicker.d.ts +13 -0
  22. package/build/components/Dial.d.ts +10 -0
  23. package/build/components/Dialog.d.ts +20 -0
  24. package/build/components/DropdownMenu.d.ts +32 -0
  25. package/build/components/FileInput.d.ts +8 -0
  26. package/build/components/Footer.d.ts +14 -0
  27. package/build/components/Form.d.ts +8 -0
  28. package/build/components/Layers.d.ts +9 -0
  29. package/build/components/List.d.ts +9 -0
  30. package/build/components/Map2D.d.ts +12 -0
  31. package/build/components/Menubar.d.ts +59 -0
  32. package/build/components/NodeTree.d.ts +26 -0
  33. package/build/components/NumberInput.d.ts +9 -0
  34. package/build/components/OTPInput.d.ts +8 -0
  35. package/build/components/Pad.d.ts +8 -0
  36. package/build/components/Pagination.d.ts +26 -0
  37. package/build/components/PocketDialog.d.ts +11 -0
  38. package/build/components/Popover.d.ts +20 -0
  39. package/build/components/Progress.d.ts +8 -0
  40. package/build/components/RadioGroup.d.ts +8 -0
  41. package/build/components/RangeInput.d.ts +11 -0
  42. package/build/components/Rate.d.ts +8 -0
  43. package/build/components/Select.d.ts +10 -0
  44. package/build/components/Sheet.d.ts +10 -0
  45. package/build/components/Sidebar.d.ts +84 -0
  46. package/build/components/SizeInput.d.ts +8 -0
  47. package/build/components/Skeleton.d.ts +5 -0
  48. package/build/components/Spinner.d.ts +9 -0
  49. package/build/components/TabSections.d.ts +11 -0
  50. package/build/components/Table.d.ts +34 -0
  51. package/build/components/Tabs.d.ts +20 -0
  52. package/build/components/Tags.d.ts +9 -0
  53. package/build/components/TextArea.d.ts +8 -0
  54. package/build/components/TextInput.d.ts +11 -0
  55. package/build/components/Title.d.ts +8 -0
  56. package/build/components/Toggle.d.ts +8 -0
  57. package/build/components/Tour.d.ts +36 -0
  58. package/build/components/Vector.d.ts +9 -0
  59. package/build/core/Area.d.ts +143 -0
  60. package/build/core/Branch.d.ts +19 -0
  61. package/build/core/Core.d.ts +1 -0
  62. package/build/core/Event.d.ts +26 -0
  63. package/build/core/Icons.d.ts +4 -0
  64. package/build/core/Namespace.d.ts +2 -0
  65. package/build/core/Namespace.js +34 -0
  66. package/build/core/Namespace.js.map +1 -0
  67. package/build/core/Panel.d.ts +538 -0
  68. package/build/core/Utils.d.ts +1 -0
  69. package/build/core/Vec2.d.ts +21 -0
  70. package/build/extensions/AssetView.d.ts +136 -0
  71. package/build/extensions/AssetView.js +1367 -0
  72. package/build/extensions/AssetView.js.map +1 -0
  73. package/build/extensions/Audio.d.ts +9 -0
  74. package/build/extensions/Audio.js +163 -0
  75. package/build/extensions/Audio.js.map +1 -0
  76. package/build/extensions/CodeEditor.d.ts +350 -0
  77. package/build/extensions/CodeEditor.js +5022 -0
  78. package/build/extensions/CodeEditor.js.map +1 -0
  79. package/build/extensions/DocMaker.d.ts +27 -0
  80. package/build/extensions/DocMaker.js +327 -0
  81. package/build/extensions/DocMaker.js.map +1 -0
  82. package/build/extensions/GraphEditor.d.ts +276 -0
  83. package/build/extensions/GraphEditor.js +2770 -0
  84. package/build/extensions/GraphEditor.js.map +1 -0
  85. package/build/extensions/ImUi.d.ts +46 -0
  86. package/build/extensions/ImUi.js +227 -0
  87. package/build/extensions/ImUi.js.map +1 -0
  88. package/build/extensions/Timeline.d.ts +670 -0
  89. package/build/extensions/Timeline.js +3955 -0
  90. package/build/extensions/Timeline.js.map +1 -0
  91. package/build/extensions/VideoEditor.d.ts +128 -0
  92. package/build/extensions/VideoEditor.js +898 -0
  93. package/build/extensions/VideoEditor.js.map +1 -0
  94. package/build/extensions/index.d.ts +8 -0
  95. package/build/extensions/index.js +10 -0
  96. package/build/extensions/index.js.map +1 -0
  97. package/build/index.all.d.ts +2 -0
  98. package/build/index.css.d.ts +4 -0
  99. package/build/index.d.ts +56 -0
  100. package/build/lexgui.all.js +28498 -0
  101. package/build/lexgui.all.js.map +1 -0
  102. package/build/lexgui.all.min.js +1 -0
  103. package/build/lexgui.all.module.js +28422 -0
  104. package/build/lexgui.all.module.js.map +1 -0
  105. package/build/lexgui.all.module.min.js +1 -0
  106. package/build/lexgui.css +939 -346
  107. package/build/lexgui.js +13406 -17286
  108. package/build/lexgui.js.map +1 -0
  109. package/build/lexgui.min.css +3 -10
  110. package/build/lexgui.min.js +1 -1
  111. package/build/lexgui.module.js +12762 -16698
  112. package/build/lexgui.module.js.map +1 -0
  113. package/build/lexgui.module.min.js +1 -1
  114. package/changelog.md +170 -74
  115. package/demo.js +162 -48
  116. package/examples/all-components.html +45 -14
  117. package/examples/asset-view.html +110 -47
  118. package/examples/code-editor.html +5 -5
  119. package/examples/dialogs.html +3 -3
  120. package/examples/editor.html +27 -13
  121. package/examples/index.html +19 -14
  122. package/examples/node-graph.html +2 -2
  123. package/examples/previews/video-editor.png +0 -0
  124. package/examples/timeline.html +1 -1
  125. package/examples/video-editor.html +2 -2
  126. package/package.json +25 -9
  127. package/build/extensions/audio.js +0 -212
  128. package/build/extensions/codeeditor.js +0 -6319
  129. package/build/extensions/docmaker.js +0 -432
  130. package/build/extensions/imui.js +0 -325
  131. package/build/extensions/nodegraph.js +0 -3696
  132. package/build/extensions/timeline.js +0 -4636
  133. package/build/extensions/videoeditor.js +0 -953
  134. package/build/lexgui-docs.css +0 -352
@@ -47,7 +47,6 @@
47
47
  }, { float: 'lt' });
48
48
 
49
49
  const dialogClosable = new LX.Dialog("Closable Dialog", p => {
50
- p.branch("Canvas");
51
50
  p.addColor("Background", "#b7a9b1");
52
51
  p.addText("Text", "Dialog Lexgui.js @jxarco", null, { placeholder: "e.g. ColorPicker", icon: "Type" });
53
52
  p.addColor("Font Color", { r: 1, g: 0.1, b: 0.6 }, (value, event) => {
@@ -62,8 +61,7 @@
62
61
  p.addSelect("Best Tool", ["@Engines", "Godot", "Unity", "Unreal Engine", "@Apps", "Visual Studio", "Visual Studio Code"], "Unity", (value, event) => {
63
62
  console.log(value);
64
63
  }, {filter: true, emptyMsg: "No engines found.", placeholder: "Search engines..."});
65
- p.merge();
66
- }, { size: ["350px", null], closable: true });
64
+ }, { size: ["350px", null], position: ["100px", "500px"], closable: true });
67
65
 
68
66
  const draggablePocketDialog = new LX.PocketDialog("Draggable PocketDialog", p => {
69
67
  p.branch("Canvas");
@@ -84,6 +82,8 @@
84
82
  p.merge();
85
83
  }, { size: ["350px", null], draggable: true });
86
84
 
85
+ const alertDialog = new LX.AlertDialog( "Are you absolutely sure?", "This action cannot be undone. This will permanently delete your account and remove your data from our servers." );
86
+
87
87
  // add canvas to left upper part
88
88
  let canvas = document.createElement('canvas');
89
89
  canvas.id = "mycanvas";
@@ -707,7 +707,7 @@
707
707
 
708
708
  panel.branch("Preferences", { icon: "Settings" });
709
709
  panel.addButton(null, "Show Notifications" + LX.badge("+99", "accent sm"));
710
- panel.addCounter("Calories Counter ", 350, (v) => { console.log(v + " calories!") }, { label: "CALORIES/DAY", max: 500 });
710
+ panel.addCounter("Calories Counter / day ", 350, (v) => { console.log(v + " calories!") }, { max: 500 });
711
711
  panel.addButton("Colored Tiny Button", "Click here!", () => { }, { buttonClass: "primary xs" });
712
712
  panel.addButton("Small Outlined Button", "Click here!", () => { }, { buttonClass: "accent sm outline" });
713
713
  panel.addButton("A Classic Button", "Click here!", () => { }, { buttonClass: "md" });
@@ -807,7 +807,6 @@
807
807
  panel.addButton(null, "Click me, Im Full Width...");
808
808
  panel.addButton("Test Button", "Reduced width...");
809
809
  panel.addSeparator();
810
- panel.addBlank(12);
811
810
  }
812
811
 
813
812
  function fillRightBottomPanel(panel, tab) {
@@ -894,7 +893,7 @@
894
893
  /************** */
895
894
  // Custom Component
896
895
 
897
- LX.ADD_CUSTOM_COMPONENT("Shader", {
896
+ LX.REGISTER_COMPONENT("Shader", {
898
897
  icon: "Box",
899
898
  default: {
900
899
  position: [0, 0],
@@ -947,7 +946,7 @@
947
946
  { name: "ID", type: "range", min: 0, max: 9, step: 1, units: "hr" },
948
947
  ],
949
948
  rowActions: [
950
- { icon: "Edit", title: "Edit Row", callback: (tableData) => { } }, // custom: you can change the data and refresh will be called later!
949
+ { icon: "Edit", title: "Edit Row", callback: (idx, bodyData) => { } }, // custom: you can change the data and refresh will be called later!
951
950
  "delete",
952
951
  "menu"
953
952
  ],
@@ -1013,7 +1012,6 @@
1013
1012
  }
1014
1013
  }
1015
1014
  });
1016
-
1017
1015
  }
1018
1016
 
1019
1017
  function openSignUpDialog()
@@ -1024,20 +1022,24 @@
1024
1022
  name: { label: "Name", value: "", icon: "User", pattern: { minLength: 3, noSpaces: true } },
1025
1023
  email: { label: "Email", value: "", icon: "AtSign", pattern: { email: true } },
1026
1024
  password: { label: "Password", value: "", type: "password", icon: "Key", pattern: { minLength: 4, digit: true } },
1027
- confirmPassword: { label: "Confirm password", value: "", type: "password", icon: "Key", pattern: { fieldMatchName: "password" } }
1025
+ confirmPassword: { label: "Confirm password", value: "", type: "password", submit: true, icon: "Key", pattern: { fieldMatchName: "password" } }
1028
1026
  };
1029
1027
 
1030
1028
  const form = p.addForm( null, formData, async (value, errors) => {
1031
1029
 
1032
- console.log(errors)
1033
-
1034
1030
  errorMsg.set( "" );
1035
1031
 
1036
1032
  if( errors.length )
1037
1033
  {
1034
+ console.log(errors)
1038
1035
  const err = errors[ 0 ];
1039
1036
  errorMsg.set( `${ err.entry }: ${ err.messages.join( "\n" ) }` );
1040
1037
  }
1038
+ else
1039
+ {
1040
+ dialog.close();
1041
+ LX.toast( "Signed Up!", "Validate your email before login.");
1042
+ }
1041
1043
  }, { primaryActionName: "SignUp" });
1042
1044
  const errorMsg = p.addTextArea( null, "", null, { inputClass: "fg-secondary", disabled: true, fitHeight: true } );
1043
1045
  }, { modal: true } );
@@ -1059,17 +1061,29 @@
1059
1061
  type: "password",
1060
1062
  placeholder: "Enter password",
1061
1063
  icon: "KeyRound",
1062
- pattern: { lowercase: true, uppercase: true, digit: true, minLength: 6 }
1064
+ pattern: { lowercase: true, uppercase: true, digit: true, minLength: 6 },
1065
+ submit: true
1063
1066
  }
1064
1067
  };
1065
1068
 
1066
- panel.addForm("Test form", formData, (value, event) => {
1067
- console.log(value);
1068
- }, { skipLabels: false, primaryActionName: "Login", secondaryActionName: "Sign Up", secondaryActionCallback: () => { console.log("Signed up") } });
1069
+ panel.addForm("Test form", formData, (value, errors) => {
1070
+ if( !errors.length )
1071
+ {
1072
+ dialog.close();
1073
+ LX.toast( "Logged in!", `Welcome ${ value.Username } :)`);
1074
+ }
1075
+ else
1076
+ {
1077
+ console.log(errors);
1078
+ }
1079
+ }, { skipLabels: false, primaryActionName: "Login" } );
1069
1080
 
1070
1081
  panel.addLabel("Or", { float: 'center' });
1071
1082
 
1072
- panel.addButton(null, "Sign up", (value, event) => { });
1083
+ panel.addButton(null, "Sign up", (value, event) => {
1084
+ dialog.close();
1085
+ openSignUpDialog();
1086
+ });
1073
1087
 
1074
1088
  }, { close: true, minimize: false, size: ["25%"], scroll: true, resizable: true, draggable: true });
1075
1089
  }
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
6
- <title>Examples - LexGUI.js </title>
6
+ <title>Examples - LexGUI</title>
7
7
  <link rel="stylesheet" href="../build/lexgui.css">
8
8
  <link rel="icon" href="../images/favicon.png">
9
9
  <style>
@@ -38,7 +38,8 @@
38
38
  // 'Immediate UI',
39
39
  'Node Graph',
40
40
  'Side Bar',
41
- "Timeline"
41
+ "Timeline",
42
+ "Video Editor"
42
43
  ];
43
44
 
44
45
  let panel = null;
@@ -57,7 +58,8 @@
57
58
  if( mobile )
58
59
  {
59
60
  const sheetArea = new LX.Area({ skipAppend: true });
60
- panel = sheetArea.addPanel({ className: "flex flex-col gap-2" });
61
+ sheetArea.root.classList.add( "overflow-scroll" );
62
+ panel = sheetArea.addPanel({ height: "auto", className: "flex flex-col gap-2" });
61
63
  iFrameArea = area;
62
64
 
63
65
  overlayButtons.splice( 0, 0, {
@@ -77,8 +79,9 @@
77
79
  { name: "Docs v" + LX.version, callback: (v, name) => { location.href = "../docs/"; } }
78
80
  ] );
79
81
  menubar.setButtonIcon("Github", "Github", () => {window.open("https://github.com/jxarco/lexgui.js/")}, { float: "left" });
82
+ menubar.siblingArea.root.classList.add( "overflow-scroll" );
80
83
 
81
- panel = leftArea.addPanel({ className: "flex flex-col gap-1" });
84
+ panel = leftArea.addPanel({ height: "auto", className: "flex flex-col gap-2" });
82
85
  iFrameArea = rightArea;
83
86
  }
84
87
 
@@ -102,17 +105,19 @@
102
105
  for( let ex of examples )
103
106
  {
104
107
  const id = ex.replace(" ", "-").toLowerCase();
105
- const options = {
106
- img: "previews/" + id + ".png",
107
- callback: function() {
108
- iframe.src = id + ".html";
109
- if( window.__currentSheet )
110
- {
111
- window.__currentSheet.destroy();
112
- }
108
+ const title = LX.makeContainer( ["auto", "auto"], "p-2 text-md fg-secondary font-semibold", ex, panel );
109
+ const container = LX.makeContainer( ["100%", "auto"], "border overflow-hidden rounded-xl cursor-pointer", "", panel );
110
+ const image = document.createElement( "img" );
111
+ image.src = "previews/" + id + ".png";
112
+ image.className = "w-full h-32 hover:scale-lg";
113
+ container.appendChild( image );
114
+ container.addEventListener( "click", (e) => {
115
+ iframe.src = id + ".html";
116
+ if( window.__currentSheet )
117
+ {
118
+ window.__currentSheet.destroy();
113
119
  }
114
- };
115
- panel.addCard( ex, options );
120
+ });
116
121
  }
117
122
  }
118
123
  </script>
@@ -20,7 +20,7 @@
20
20
  <script type="module">
21
21
 
22
22
  import { LX } from 'lexgui';
23
- import 'lexgui/extensions/nodegraph.js';
23
+ import { GraphEditor } from 'lexgui/extensions/GraphEditor.js';
24
24
 
25
25
  // init library and get main area
26
26
  let area = await LX.init();
@@ -43,7 +43,7 @@
43
43
  canvas.height = bounding.height;
44
44
  };
45
45
 
46
- let graphEditor = new LX.GraphEditor( bottomArea, {
46
+ let graphEditor = new GraphEditor( bottomArea, {
47
47
  sidebar: false,
48
48
  } );
49
49
 
@@ -18,7 +18,7 @@
18
18
  <script type="module">
19
19
 
20
20
  import { LX } from 'lexgui';
21
- import { Timeline, KeyFramesTimeline, ClipsTimeline } from 'lexgui/extensions/timeline.js';
21
+ import { Timeline, KeyFramesTimeline, ClipsTimeline } from 'lexgui/extensions/Timeline.js';
22
22
 
23
23
  // init library and get main area
24
24
  let area = await LX.init();
@@ -20,7 +20,7 @@
20
20
  <script type="module">
21
21
 
22
22
  import { LX } from 'lexgui';
23
- import { VideoEditor } from 'lexgui/extensions/videoeditor.js';
23
+ import { VideoEditor } from 'lexgui/extensions/VideoEditor.js';
24
24
 
25
25
  class Window {
26
26
  constructor( timeline, options = {} ) {
@@ -182,7 +182,7 @@
182
182
  video.src = "../data/video.mp4";
183
183
  videoArea.attach(video);
184
184
 
185
- const videoEditor = new LX.VideoEditor(leftArea, { videoArea, video, crop: true, loop: true })
185
+ const videoEditor = new LX.VideoEditor(leftArea, { videoArea, video, crop: true, loop: true, handleStyle: {backgroundColor: "white"} });
186
186
  videoEditor.loadVideo();
187
187
 
188
188
  const canvas = document.createElement('canvas');
package/package.json CHANGED
@@ -1,17 +1,20 @@
1
1
  {
2
2
  "name": "lexgui",
3
- "version": "0.7.15",
3
+ "version": "8.1.0",
4
4
  "description": "JS library to create web graphical user interfaces",
5
5
  "type": "module",
6
6
  "main": "./build/lexgui.js",
7
7
  "module": "./build/lexgui.module.js",
8
+ "exports": {
9
+ "require": "./build/lexgui.js",
10
+ "import": "./build/lexgui.module.js"
11
+ },
8
12
  "repository": {
9
13
  "type": "git",
10
14
  "url": "https://github.com/jxarco/lexgui.js"
11
15
  },
12
16
  "files": [
13
17
  "build",
14
- "build/extensions",
15
18
  "examples",
16
19
  "LICENSE",
17
20
  "package.json",
@@ -21,7 +24,7 @@
21
24
  ],
22
25
  "keywords": [
23
26
  "lexgui",
24
- "lexgui.js",
27
+ "typescript",
25
28
  "javascript",
26
29
  "editor",
27
30
  "gui",
@@ -36,13 +39,26 @@
36
39
  "url": "https://github.com/jxarco/lexgui.js/issues"
37
40
  },
38
41
  "scripts": {
39
- "rollup-js": "rollup -c rollup.build.config.js",
40
- "minify-css": "cleancss -o build/lexgui.min.css build/lexgui.css",
41
- "minify": "npm run rollup-js && npm run minify-css",
42
- "legacy": "python build-legacy.py",
43
- "build": "npm run legacy && npm run minify"
42
+ "format": "dprint fmt",
43
+ "format:check": "dprint check",
44
+ "colors": "node generate-colors.js",
45
+ "clean:css": "rimraf build/lexgui.css && rimraf build/lexgui.min.css",
46
+ "clean": "rimraf build",
47
+ "bundle": "rollup -c",
48
+ "bundle:ts": "rollup -c rollup.ts.build.config.js",
49
+ "build:ts": "tsc --project tsconfig.all.json",
50
+ "build": "npm run bundle:ts"
44
51
  },
45
52
  "devDependencies": {
46
- "@rollup/plugin-terser": "^0.4.4"
53
+ "@rollup/plugin-alias": "^6.0.0",
54
+ "@rollup/plugin-terser": "^0.4.4",
55
+ "cssnano": "^7.1.2",
56
+ "dprint": "^0.50.2",
57
+ "postcss": "^8.5.6",
58
+ "rimraf": "^5.0.10",
59
+ "rollup": "^4.53.2",
60
+ "rollup-plugin-postcss": "^4.0.2",
61
+ "rollup-plugin-typescript2": "^0.36.0",
62
+ "typescript": "^5.9.3"
47
63
  }
48
64
  }
@@ -1,212 +0,0 @@
1
- import { LX } from 'lexgui';
2
-
3
- if( !LX )
4
- {
5
- throw("lexgui.js missing!");
6
- }
7
-
8
- LX.extensions.push( 'Audio' );
9
-
10
- /**
11
- * @class Knob
12
- * @description Knob Component
13
- */
14
-
15
- class Knob extends LX.BaseComponent {
16
-
17
- constructor( name, value, min, max, callback, options = {} ) {
18
-
19
- if( value.constructor == Number )
20
- {
21
- value = LX.clamp( value, min, max );
22
- value = options.precision ? LX.round( value, options.precision ) : value;
23
- }
24
-
25
- super( LX.BaseComponent.KNOB, name, value, options );
26
-
27
- this.onGetValue = () => {
28
- return innerKnobCircle.value;
29
- };
30
-
31
- this.onSetValue = ( newValue, skipCallback ) => {
32
- innerSetValue( newValue );
33
- LX.BaseComponent._dispatchEvent( innerKnobCircle, "change", skipCallback );
34
- };
35
-
36
- this.onResize = ( rect ) => {
37
- const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
38
- container.style.width = `calc( 100% - ${ realNameWidth })`;
39
- };
40
-
41
- const snapEnabled = ( options.snap && options.snap.constructor == Number );
42
- const ticks = [];
43
- if( snapEnabled )
44
- {
45
- const range = (max - min) / options.snap;
46
- for( let i = 0; i < ( options.snap + 1 ); ++i )
47
- {
48
- ticks.push( min + (i * range) );
49
- }
50
- }
51
-
52
- var container = document.createElement( 'div' );
53
- container.className = "lexknob";
54
- container.addClass( options.size );
55
- container.addClass( snapEnabled ? "show-ticks" : null );
56
-
57
- let knobCircle = document.createElement( 'div' );
58
- knobCircle.className = "knobcircle";
59
- if( snapEnabled )
60
- {
61
- knobCircle.style.setProperty( "--knob-snap-mark", ( 270 / options.snap ) + "deg" );
62
- }
63
-
64
- let innerKnobCircle = document.createElement( 'div' );
65
- innerKnobCircle.className = "innerknobcircle";
66
- innerKnobCircle.min = min;
67
- innerKnobCircle.max = max;
68
- knobCircle.appendChild( innerKnobCircle );
69
-
70
- let knobMarker = document.createElement( 'div' );
71
- knobMarker.className = "knobmarker";
72
- innerKnobCircle.appendChild( knobMarker );
73
- innerKnobCircle.value = innerKnobCircle.iValue = value;
74
-
75
- let mustSnap = false;
76
- let innerSetValue = function( v ) {
77
- // Convert val between (-135 and 135)
78
- const angle = LX.remapRange( v, innerKnobCircle.min, innerKnobCircle.max, -135.0, 135.0 );
79
- innerKnobCircle.style.rotate = angle + 'deg';
80
- innerKnobCircle.value = v;
81
- }
82
-
83
- const angle = LX.remapRange( value, min, max, -135.0, 135.0 );
84
- innerKnobCircle.style.rotate = angle + 'deg';
85
-
86
- if( options.disabled )
87
- {
88
- container.addClass( "disabled" );
89
- }
90
-
91
- innerKnobCircle.addEventListener( "change", e => {
92
-
93
- const knob = e.target;
94
-
95
- const skipCallback = e.detail;
96
-
97
- if( mustSnap )
98
- {
99
- knob.value = ticks.reduce(( prev, curr ) => Math.abs( curr - knob.value ) < Math.abs( prev - knob.value ) ? curr : prev );
100
- }
101
-
102
- let val = knob.value = LX.clamp( knob.value, knob.min, knob.max );
103
- val = options.precision ? LX.round( val, options.precision ) : val;
104
-
105
- innerSetValue( val );
106
-
107
- // Reset button (default value)
108
- if( !skipCallback )
109
- {
110
- let btn = this.root.querySelector( ".lexcomponentname .lexicon" );
111
- if( btn ) btn.style.display = val != innerKnobCircle.iValue ? "block": "none";
112
-
113
- if( !( snapEnabled && !mustSnap ) )
114
- {
115
- this._trigger( new LX.IEvent( name, val, e ), callback );
116
- mustSnap = false;
117
- }
118
- }
119
-
120
- }, { passive: false });
121
-
122
- // Add drag input
123
-
124
- innerKnobCircle.addEventListener( "mousedown", inner_mousedown );
125
-
126
- var that = this;
127
-
128
- function inner_mousedown( e ) {
129
-
130
- if( document.activeElement == innerKnobCircle || options.disabled )
131
- {
132
- return;
133
- }
134
-
135
- var doc = that.root.ownerDocument;
136
- doc.addEventListener("mousemove",inner_mousemove);
137
- doc.addEventListener("mouseup",inner_mouseup);
138
- document.body.classList.add('noevents');
139
-
140
- if( !document.pointerLockElement )
141
- {
142
- container.requestPointerLock();
143
- }
144
-
145
- e.stopImmediatePropagation();
146
- e.stopPropagation();
147
- }
148
-
149
- function inner_mousemove( e ) {
150
-
151
- let dt = -e.movementY;
152
-
153
- if ( dt != 0 )
154
- {
155
- let mult = options.step ?? 1;
156
- if(e.shiftKey) mult *= 10;
157
- else if(e.altKey) mult *= 0.1;
158
- let new_value = (innerKnobCircle.value - mult * dt);
159
- innerKnobCircle.value = new_value;
160
- LX.BaseComponent._dispatchEvent( innerKnobCircle, 'change' );
161
- }
162
-
163
- e.stopPropagation();
164
- e.preventDefault();
165
- }
166
-
167
- function inner_mouseup( e ) {
168
-
169
- var doc = that.root.ownerDocument;
170
- doc.removeEventListener( 'mousemove', inner_mousemove );
171
- doc.removeEventListener( 'mouseup', inner_mouseup );
172
- document.body.classList.remove( 'noevents' );
173
-
174
- // Snap if necessary
175
- if( snapEnabled )
176
- {
177
- mustSnap = true;
178
- LX.BaseComponent._dispatchEvent( innerKnobCircle, 'change' );
179
- }
180
-
181
- if( document.pointerLockElement )
182
- {
183
- document.exitPointerLock();
184
- }
185
- }
186
-
187
- container.appendChild( knobCircle );
188
-
189
- this.root.appendChild( container );
190
-
191
- LX.doAsync( this.onResize.bind( this ) );
192
- }
193
- }
194
-
195
- LX.Knob = Knob;
196
-
197
- /**
198
- * @method addKnob
199
- * @param {String} name Component name
200
- * @param {Number} value Knob value
201
- * @param {Number} min Min Knob value
202
- * @param {Number} max Max Knob value
203
- * @param {Function} callback Callback function on change
204
- * @param {*} options:
205
- * minLabel (String): Label to show as min value
206
- * maxLabel (String): Label to show as max value
207
- */
208
-
209
- LX.Panel.prototype.addKnob = function( name, value, min, max, callback, options = {} ) {
210
- const component = new Knob( name, value, min, max, callback, options );
211
- return this._attachComponent( component );
212
- }