lexgui 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -5
- package/build/components/imui.js +315 -0
- package/build/components/nodegraph.js +395 -395
- package/build/components/timeline.js +24 -28
- package/build/lexgui.js +26 -3
- package/build/lexgui.module.js +26 -3
- package/demo.js +0 -2
- package/examples/area_tabs.html +14 -4
- package/examples/asset_view.html +19 -9
- package/examples/code_editor.html +14 -4
- package/examples/dialogs.html +14 -4
- package/examples/immediate_ui.html +77 -0
- package/examples/index.html +18 -6
- package/examples/node_graph.html +15 -5
- package/examples/overlay_area.html +15 -5
- package/examples/previews/asset_view.png +0 -0
- package/examples/previews/code_editor.png +0 -0
- package/examples/previews/node_graph.png +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
**lexgui.js** is a lightweight JavaScript library that allows you to create web interfaces using only JavaScript, HTML, and CSS. This library provides an easy-to-use API for building dynamic and interactive user interfaces without the need for complex frameworks or libraries. With lexgui.js, you can create custom UI components, handle user interactions, and update the interface dynamically.
|
|
4
4
|
|
|
5
5
|
<img src="data/Screenshot.png" alt="Screenshot" style="width: 100%"/>
|
|
6
|
-
<
|
|
7
|
-
<
|
|
8
|
-
<img src="data/
|
|
9
|
-
|
|
6
|
+
<table>
|
|
7
|
+
<tr>
|
|
8
|
+
<td valign="top"><img src="data/Screenshot_Godot.png"/></td>
|
|
9
|
+
<td valign="top"><img src="data/Screenshot_Code.png"/></td>
|
|
10
|
+
</tr>
|
|
11
|
+
</table>
|
|
10
12
|
|
|
11
13
|
## Docs
|
|
12
14
|
|
|
@@ -16,12 +18,24 @@ The library documentation is in progress but you can check it [here](https://jxa
|
|
|
16
18
|
|
|
17
19
|
Look at this [examples](https://jxarco.github.io/lexgui.js/examples/) to see how to create the different widgets and components!
|
|
18
20
|
|
|
21
|
+
## Projects using lexgui.js
|
|
22
|
+
|
|
23
|
+
### [Animics](https://github.com/upf-gti/SignON-editor) (EU H2020 SignON project)
|
|
24
|
+
|
|
25
|
+
<img src="data/scriptAnimation_signon.png" alt="scriptAnimation_signon"/>
|
|
26
|
+
|
|
27
|
+
### [Performs](https://github.com/upf-gti/SignON-realizer) (EU H2020 SignON project)
|
|
28
|
+
|
|
29
|
+
<img src="data/realizer_signon.png" alt="scriptAnimation_signon"/>
|
|
30
|
+
|
|
19
31
|
## Contributors
|
|
20
32
|
|
|
21
33
|
* Alex Rodríguez @jxarco
|
|
22
34
|
* Eva Valls @evallsg
|
|
23
35
|
|
|
24
|
-
|
|
36
|
+
## Feedback/Issues
|
|
37
|
+
|
|
38
|
+
You can use the [repository issues section](https://github.com/jxarco/lexgui.js/issues) or simply write any feedback to alexroco.30@gmail.com.
|
|
25
39
|
|
|
26
40
|
## Component Features
|
|
27
41
|
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { LX } from 'lexgui';
|
|
2
|
+
|
|
3
|
+
if(!LX) {
|
|
4
|
+
throw("lexgui.js missing!");
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
LX.components.push( 'ImUI' );
|
|
8
|
+
|
|
9
|
+
function swapElements (obj, a, b) {
|
|
10
|
+
[obj[a], obj[b]] = [obj[b], obj[a]];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function swapArrayElements (array, id0, id1) {
|
|
14
|
+
[array[id0], array[id1]] = [array[id1], array[id0]];
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @class ImUI
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
class ImUI {
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {*} options
|
|
25
|
+
*
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
constructor( canvas, options = {} ) {
|
|
29
|
+
|
|
30
|
+
console.assert( canvas );
|
|
31
|
+
|
|
32
|
+
// To capture key events
|
|
33
|
+
canvas.tabIndex = -1;
|
|
34
|
+
|
|
35
|
+
canvas.addEventListener( 'keydown', this._processKey.bind(this), true);
|
|
36
|
+
canvas.addEventListener( 'mousedown', this._processMouse.bind(this) );
|
|
37
|
+
canvas.addEventListener( 'mouseup', this._processMouse.bind(this) );
|
|
38
|
+
canvas.addEventListener( 'mousemove', this._processMouse.bind(this) );
|
|
39
|
+
canvas.addEventListener( 'click', this._processMouse.bind(this) );
|
|
40
|
+
|
|
41
|
+
// this.font = new FontFace("Ubuntu", "url(../data/Ubuntu-Bold.ttf)");
|
|
42
|
+
// this.font.load().then(
|
|
43
|
+
// ( font ) => {
|
|
44
|
+
// document.fonts.add( font );
|
|
45
|
+
// if( options.onready ) options.onready();
|
|
46
|
+
// },
|
|
47
|
+
// (err) => {
|
|
48
|
+
// console.error(err);
|
|
49
|
+
// },
|
|
50
|
+
// );
|
|
51
|
+
|
|
52
|
+
// Widgets
|
|
53
|
+
|
|
54
|
+
this.widgets = { };
|
|
55
|
+
|
|
56
|
+
// Mouse state
|
|
57
|
+
|
|
58
|
+
this.mousePosition = new LX.vec2();
|
|
59
|
+
|
|
60
|
+
this.root = this.canvas = canvas;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
_processKey(e) {
|
|
64
|
+
|
|
65
|
+
var key = e.key ?? e.detail.key;
|
|
66
|
+
console.log( key );
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
_processMouse(e) {
|
|
70
|
+
|
|
71
|
+
if( e.type == 'mousedown' )
|
|
72
|
+
{
|
|
73
|
+
this.mouseDown = true;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
else if( e.type == 'mouseup' )
|
|
77
|
+
{
|
|
78
|
+
this._processClick(e);
|
|
79
|
+
this.mouseDown = false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
else if( e.type == 'mousemove' )
|
|
83
|
+
{
|
|
84
|
+
this.mousePosition.set( e.clientX, e.clientY );
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
_processClick( e ) {
|
|
89
|
+
|
|
90
|
+
this.eventClick = e;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @method Button
|
|
95
|
+
* @param {String} text
|
|
96
|
+
* @param {Number} x
|
|
97
|
+
* @param {Number} y
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
Button( text, x, y, callback ) {
|
|
101
|
+
|
|
102
|
+
const ctx = this.canvas.getContext("2d");
|
|
103
|
+
|
|
104
|
+
// Element properties
|
|
105
|
+
|
|
106
|
+
let fontSize = 16;
|
|
107
|
+
ctx.font = fontSize + "px Arial";
|
|
108
|
+
|
|
109
|
+
let padding = new LX.vec2( 12, 8 );
|
|
110
|
+
let position = new LX.vec2( x, y );
|
|
111
|
+
|
|
112
|
+
const metrics = ctx.measureText( text );
|
|
113
|
+
let size = new LX.vec2( metrics.width, metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent );
|
|
114
|
+
|
|
115
|
+
// Get mouse state
|
|
116
|
+
|
|
117
|
+
const hovered = this.mousePosition.x >= position.x && this.mousePosition.x <= (position.x + size.x + padding.x * 2.0)
|
|
118
|
+
&& this.mousePosition.y >= position.y && this.mousePosition.y <= (position.y + size.y + padding.y * 2.0);
|
|
119
|
+
|
|
120
|
+
const active = hovered && this.mouseDown;
|
|
121
|
+
|
|
122
|
+
// Draw button
|
|
123
|
+
|
|
124
|
+
ctx.fillStyle = active ? "#666" : (hovered ? "#444" : "#222");
|
|
125
|
+
ctx.fillRect( position.x, position.y, size.x + padding.x * 2.0, size.y + padding.y * 2.0 );
|
|
126
|
+
|
|
127
|
+
// Draw text
|
|
128
|
+
|
|
129
|
+
ctx.fillStyle = hovered ? "#fff" : "#ddd";
|
|
130
|
+
ctx.fillText( text, position.x + padding.x, position.y + metrics.actualBoundingBoxAscent + padding.y );
|
|
131
|
+
|
|
132
|
+
if( !hovered )
|
|
133
|
+
{
|
|
134
|
+
document.body.style.cursor = "default";
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Pointer cursor on hover
|
|
139
|
+
document.body.style.cursor = "pointer";
|
|
140
|
+
|
|
141
|
+
if( this.eventClick )
|
|
142
|
+
{
|
|
143
|
+
if(callback) callback();
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* @method Slider
|
|
152
|
+
* @param {String} text
|
|
153
|
+
* @param {Number} x
|
|
154
|
+
* @param {Number} y
|
|
155
|
+
* @param {Number} value
|
|
156
|
+
*/
|
|
157
|
+
|
|
158
|
+
Slider( text, x, y, value = 0, callback ) {
|
|
159
|
+
|
|
160
|
+
const ctx = this.canvas.getContext("2d");
|
|
161
|
+
|
|
162
|
+
// Store slider value
|
|
163
|
+
|
|
164
|
+
if(!this.widgets[ text ])
|
|
165
|
+
this.widgets[ text ] = { value: value };
|
|
166
|
+
else
|
|
167
|
+
value = this.widgets[ text ].value;
|
|
168
|
+
|
|
169
|
+
// Element properties
|
|
170
|
+
|
|
171
|
+
let fontSize = 16;
|
|
172
|
+
ctx.font = fontSize + "px Arial";
|
|
173
|
+
|
|
174
|
+
let padding = new LX.vec2( 12, 8 );
|
|
175
|
+
let position = new LX.vec2( x, y );
|
|
176
|
+
|
|
177
|
+
const metrics = ctx.measureText( text );
|
|
178
|
+
let size = new LX.vec2( metrics.width, metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent );
|
|
179
|
+
|
|
180
|
+
// Get mouse state
|
|
181
|
+
|
|
182
|
+
const hovered = this.mousePosition.x >= position.x && this.mousePosition.x <= (position.x + size.x + padding.x * 2.0)
|
|
183
|
+
&& this.mousePosition.y >= position.y && this.mousePosition.y <= (position.y + size.y + padding.y * 2.0);
|
|
184
|
+
|
|
185
|
+
const active = hovered && this.mouseDown;
|
|
186
|
+
|
|
187
|
+
// Draw box
|
|
188
|
+
|
|
189
|
+
ctx.fillStyle = hovered ? "#444" : "#222";
|
|
190
|
+
ctx.fillRect( position.x, position.y, size.x + padding.x * 2.0, size.y + padding.y * 2.0 );
|
|
191
|
+
|
|
192
|
+
// Draw thumb
|
|
193
|
+
|
|
194
|
+
let thumbSize = new LX.vec2( 12, size.y );
|
|
195
|
+
|
|
196
|
+
const min = position.x;
|
|
197
|
+
const max = position.x + size.x + padding.x * 2.0 - thumbSize.x;
|
|
198
|
+
|
|
199
|
+
if(active)
|
|
200
|
+
{
|
|
201
|
+
value = LX.UTILS.clamp((this.mousePosition.x - min - thumbSize.x * 0.5) / (max - min), 0.0, 1.0);
|
|
202
|
+
this.widgets[ text ].value = value;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
let thumbPos = new LX.vec2( min + (max - position.x) * value, position.y );
|
|
206
|
+
|
|
207
|
+
ctx.fillStyle = active ? "#bbb" : (hovered ? "#777" : "#888");
|
|
208
|
+
ctx.fillRect( thumbPos.x, thumbPos.y, thumbSize.x, thumbSize.y + padding.y * 2.0 );
|
|
209
|
+
|
|
210
|
+
// Draw text
|
|
211
|
+
|
|
212
|
+
ctx.fillStyle = hovered ? "#fff" : "#ddd";
|
|
213
|
+
ctx.fillText( text, position.x + padding.x, position.y + metrics.actualBoundingBoxAscent + padding.y );
|
|
214
|
+
|
|
215
|
+
if( !hovered )
|
|
216
|
+
{
|
|
217
|
+
document.body.style.cursor = "default";
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Pointer cursor on hover
|
|
222
|
+
document.body.style.cursor = "pointer";
|
|
223
|
+
|
|
224
|
+
if( active )
|
|
225
|
+
{
|
|
226
|
+
if(callback) callback( value );
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* @method Checkbox
|
|
232
|
+
* @param {String} text
|
|
233
|
+
* @param {Number} x
|
|
234
|
+
* @param {Number} y
|
|
235
|
+
* @param {Number} value
|
|
236
|
+
*/
|
|
237
|
+
|
|
238
|
+
Checkbox( text, x, y, value = false, callback ) {
|
|
239
|
+
|
|
240
|
+
const ctx = this.canvas.getContext("2d");
|
|
241
|
+
|
|
242
|
+
// Store slider value
|
|
243
|
+
|
|
244
|
+
if(!this.widgets[ text ])
|
|
245
|
+
this.widgets[ text ] = { value: value };
|
|
246
|
+
else
|
|
247
|
+
value = this.widgets[ text ].value;
|
|
248
|
+
|
|
249
|
+
// Element properties
|
|
250
|
+
|
|
251
|
+
let fontSize = 16;
|
|
252
|
+
ctx.font = fontSize + "px Arial";
|
|
253
|
+
|
|
254
|
+
let padding = new LX.vec2( 12, 8 );
|
|
255
|
+
let position = new LX.vec2( x, y );
|
|
256
|
+
|
|
257
|
+
const metrics = ctx.measureText( text );
|
|
258
|
+
let size = new LX.vec2( metrics.width, metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent );
|
|
259
|
+
|
|
260
|
+
let boxMargin = 12;
|
|
261
|
+
let fullSize = new LX.vec2(boxMargin * 2.0, 0);
|
|
262
|
+
fullSize.add( size );
|
|
263
|
+
|
|
264
|
+
// Get mouse state
|
|
265
|
+
|
|
266
|
+
const boxStartX = position.x + size.x + padding.x + boxMargin;
|
|
267
|
+
const boxStartY = position.y + padding.y;
|
|
268
|
+
const hovered = this.mousePosition.x >= boxStartX && this.mousePosition.x <= (boxStartX + size.y)
|
|
269
|
+
&& this.mousePosition.y >= boxStartY && this.mousePosition.y <= (boxStartY + size.y);
|
|
270
|
+
|
|
271
|
+
const active = hovered && this.mouseDown;
|
|
272
|
+
const pressed = hovered && this.eventClick;
|
|
273
|
+
|
|
274
|
+
// Draw button
|
|
275
|
+
|
|
276
|
+
ctx.fillStyle = active ? "#666" : (hovered ? "#444" : "#222");
|
|
277
|
+
ctx.fillRect( position.x, position.y, fullSize.x + padding.x * 2.0, fullSize.y + padding.y * 2.0 );
|
|
278
|
+
|
|
279
|
+
// Draw checkbox
|
|
280
|
+
|
|
281
|
+
if( pressed )
|
|
282
|
+
{
|
|
283
|
+
value = !value;
|
|
284
|
+
this.widgets[ text ].value = value;
|
|
285
|
+
if(callback) callback( value );
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
ctx.fillStyle = value ? (active ? "#ddd" : (hovered ? "#6074e7" : "#3e57e4")) :
|
|
289
|
+
(active ? "#bbb" : (hovered ? "#777" : "#888"));
|
|
290
|
+
ctx.fillRect( position.x + size.x + padding.x + boxMargin, position.y + padding.y, size.y, size.y );
|
|
291
|
+
|
|
292
|
+
// Draw text
|
|
293
|
+
|
|
294
|
+
ctx.fillStyle = hovered ? "#fff" : "#ddd";
|
|
295
|
+
ctx.fillText( text, position.x + padding.x, position.y + metrics.actualBoundingBoxAscent + padding.y );
|
|
296
|
+
|
|
297
|
+
// Pointer cursor on hover
|
|
298
|
+
document.body.style.cursor = hovered ? "pointer" : "default";
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* @method endFrame
|
|
303
|
+
* @description Clears the information stored during the last frame
|
|
304
|
+
*/
|
|
305
|
+
|
|
306
|
+
endFrame() {
|
|
307
|
+
|
|
308
|
+
this.eventClick = null;
|
|
309
|
+
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
LX.ImUI = ImUI;
|
|
314
|
+
|
|
315
|
+
export { ImUI };
|