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 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
- <div style="display: flex">
7
- <img src="data/Screenshot_Godot.png" alt="ScreenshotGodot" style="width: 50%"/>
8
- <img src="data/Screenshot_Code.png" alt="ScreenshotCode" style="width: 50%"/>
9
- </div>
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 };