lexgui 0.1.36 → 0.1.37
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 +71 -15
- package/build/components/audio.js +179 -0
- package/build/components/timeline.js +2761 -3119
- package/build/components/videoeditor.js +10 -2
- package/build/lexgui.css +83 -2
- package/build/lexgui.js +111 -55
- package/build/lexgui.module.js +112 -53
- package/changelog.md +11 -1
- package/demo.js +3 -1
- package/examples/timeline.html +33 -21
- package/package.json +1 -1
package/build/lexgui.module.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
var LX = {
|
|
11
|
-
version: "0.1.
|
|
11
|
+
version: "0.1.37",
|
|
12
12
|
ready: false,
|
|
13
13
|
components: [], // specific pre-build components
|
|
14
14
|
signals: {} // events and triggers
|
|
@@ -25,7 +25,10 @@ LX.CURVE_MOVEOUT_CLAMP = 0;
|
|
|
25
25
|
LX.CURVE_MOVEOUT_DELETE = 1;
|
|
26
26
|
|
|
27
27
|
function clamp( num, min, max ) { return Math.min( Math.max( num, min ), max ); }
|
|
28
|
-
function round(
|
|
28
|
+
function round( number, precision ) { return +(( number ).toFixed( precision ?? 2 ).replace( /([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/, '$1' )); }
|
|
29
|
+
|
|
30
|
+
LX.clamp = clamp;
|
|
31
|
+
LX.round = round;
|
|
29
32
|
|
|
30
33
|
function getSupportedDOMName( string )
|
|
31
34
|
{
|
|
@@ -109,6 +112,8 @@ function simple_guidGenerator() {
|
|
|
109
112
|
return (S4()+"-"+S4()+"-"+S4());
|
|
110
113
|
}
|
|
111
114
|
|
|
115
|
+
LX.guidGenerator = simple_guidGenerator;
|
|
116
|
+
|
|
112
117
|
// Timer that works everywhere (from litegraph.js)
|
|
113
118
|
if (typeof performance != "undefined") {
|
|
114
119
|
LX.getTime = performance.now.bind(performance);
|
|
@@ -300,11 +305,18 @@ function create_global_searchbar( root ) {
|
|
|
300
305
|
else
|
|
301
306
|
{
|
|
302
307
|
for( let c of LX.components )
|
|
303
|
-
|
|
308
|
+
{
|
|
309
|
+
if( !LX[c] || !LX[c].prototype.onKeyPressed )
|
|
304
310
|
{
|
|
305
|
-
|
|
306
|
-
for( let i of instances ) i.onKeyPressed( e );
|
|
311
|
+
continue;
|
|
307
312
|
}
|
|
313
|
+
|
|
314
|
+
const instances = LX.CodeEditor.getInstances();
|
|
315
|
+
for( let i of instances )
|
|
316
|
+
{
|
|
317
|
+
i.onKeyPressed( e );
|
|
318
|
+
}
|
|
319
|
+
}
|
|
308
320
|
}
|
|
309
321
|
});
|
|
310
322
|
|
|
@@ -631,6 +643,8 @@ class IEvent {
|
|
|
631
643
|
}
|
|
632
644
|
};
|
|
633
645
|
|
|
646
|
+
LX.IEvent = IEvent;
|
|
647
|
+
|
|
634
648
|
class TreeEvent {
|
|
635
649
|
|
|
636
650
|
static NONE = 0;
|
|
@@ -2448,6 +2462,7 @@ class Widget {
|
|
|
2448
2462
|
static CONTENT = 20;
|
|
2449
2463
|
static CUSTOM = 21;
|
|
2450
2464
|
static SEPARATOR = 22;
|
|
2465
|
+
static KNOB = 23;
|
|
2451
2466
|
|
|
2452
2467
|
static NO_CONTEXT_TYPES = [
|
|
2453
2468
|
Widget.BUTTON,
|
|
@@ -2456,7 +2471,7 @@ class Widget {
|
|
|
2456
2471
|
Widget.PROGRESS
|
|
2457
2472
|
];
|
|
2458
2473
|
|
|
2459
|
-
constructor(name, type, options) {
|
|
2474
|
+
constructor( name, type, options ) {
|
|
2460
2475
|
this.name = name;
|
|
2461
2476
|
this.type = type;
|
|
2462
2477
|
this.options = options;
|
|
@@ -2464,10 +2479,12 @@ class Widget {
|
|
|
2464
2479
|
|
|
2465
2480
|
value() {
|
|
2466
2481
|
|
|
2467
|
-
if(this.onGetValue)
|
|
2482
|
+
if( this.onGetValue )
|
|
2483
|
+
{
|
|
2468
2484
|
return this.onGetValue();
|
|
2485
|
+
}
|
|
2469
2486
|
|
|
2470
|
-
console.warn("Can't get value of " + this.typeName());
|
|
2487
|
+
console.warn( "Can't get value of " + this.typeName() );
|
|
2471
2488
|
}
|
|
2472
2489
|
|
|
2473
2490
|
set( value, skipCallback = false, signalName = "" ) {
|
|
@@ -2527,6 +2544,7 @@ class Widget {
|
|
|
2527
2544
|
case Widget.LIST: return "List";
|
|
2528
2545
|
case Widget.TAGS: return "Tags";
|
|
2529
2546
|
case Widget.CURVE: return "Curve";
|
|
2547
|
+
case Widget.KNOB: return "Knob";
|
|
2530
2548
|
case Widget.CUSTOM: return this.customName;
|
|
2531
2549
|
}
|
|
2532
2550
|
}
|
|
@@ -5084,6 +5102,7 @@ class Panel {
|
|
|
5084
5102
|
* precision: The number of digits to appear after the decimal point
|
|
5085
5103
|
* min, max: Min and Max values for the input
|
|
5086
5104
|
* skipSlider: If there are min and max values, skip the slider
|
|
5105
|
+
* units: Unit as string added to the end of the value
|
|
5087
5106
|
*/
|
|
5088
5107
|
|
|
5089
5108
|
addNumber( name, value, callback, options = {} ) {
|
|
@@ -5094,7 +5113,7 @@ class Panel {
|
|
|
5094
5113
|
return +vecinput.value;
|
|
5095
5114
|
};
|
|
5096
5115
|
widget.onSetValue = ( newValue, skipCallback ) => {
|
|
5097
|
-
vecinput.value = newValue;
|
|
5116
|
+
vecinput.value = round( newValue, options.precision );
|
|
5098
5117
|
Panel._dispatch_event( vecinput, "change", skipCallback );
|
|
5099
5118
|
};
|
|
5100
5119
|
|
|
@@ -5119,27 +5138,48 @@ class Panel {
|
|
|
5119
5138
|
box.className = "numberbox";
|
|
5120
5139
|
|
|
5121
5140
|
let vecinput = document.createElement( 'input' );
|
|
5141
|
+
vecinput.id = "number_" + simple_guidGenerator();
|
|
5122
5142
|
vecinput.className = "vecinput";
|
|
5123
5143
|
vecinput.min = options.min ?? -1e24;
|
|
5124
5144
|
vecinput.max = options.max ?? 1e24;
|
|
5125
5145
|
vecinput.step = options.step ?? "any";
|
|
5126
5146
|
vecinput.type = "number";
|
|
5127
|
-
vecinput.id = "number_" + simple_guidGenerator();
|
|
5128
5147
|
|
|
5129
5148
|
if( value.constructor == Number )
|
|
5130
5149
|
{
|
|
5131
5150
|
value = clamp( value, +vecinput.min, +vecinput.max );
|
|
5132
|
-
value =
|
|
5151
|
+
value = round( value, options.precision );
|
|
5133
5152
|
}
|
|
5134
5153
|
|
|
5135
5154
|
vecinput.value = vecinput.iValue = value;
|
|
5136
5155
|
box.appendChild( vecinput );
|
|
5137
5156
|
|
|
5138
|
-
let
|
|
5139
|
-
|
|
5140
|
-
|
|
5157
|
+
let measureRealWidth = function( value, paddingPlusMargin = 8 ) {
|
|
5158
|
+
var i = document.createElement( "span" );
|
|
5159
|
+
i.className = "lexinputmeasure";
|
|
5160
|
+
i.innerHTML = value;
|
|
5161
|
+
document.body.appendChild( i );
|
|
5162
|
+
var rect = i.getBoundingClientRect();
|
|
5163
|
+
LX.UTILS.deleteElement( i );
|
|
5164
|
+
return rect.width + paddingPlusMargin;
|
|
5165
|
+
}
|
|
5141
5166
|
|
|
5142
|
-
if( options.
|
|
5167
|
+
if( options.units )
|
|
5168
|
+
{
|
|
5169
|
+
let unitSpan = document.createElement( 'span' );
|
|
5170
|
+
unitSpan.className = "lexunit";
|
|
5171
|
+
unitSpan.innerText = options.units;
|
|
5172
|
+
unitSpan.style.left = measureRealWidth( vecinput.value ) + "px";
|
|
5173
|
+
vecinput.unitSpan = unitSpan;
|
|
5174
|
+
box.appendChild( unitSpan );
|
|
5175
|
+
}
|
|
5176
|
+
|
|
5177
|
+
let dragIcon = document.createElement( 'a' );
|
|
5178
|
+
dragIcon.className = "fa-solid fa-arrows-up-down drag-icon hidden";
|
|
5179
|
+
box.appendChild( dragIcon );
|
|
5180
|
+
|
|
5181
|
+
if( options.disabled )
|
|
5182
|
+
{
|
|
5143
5183
|
vecinput.disabled = true;
|
|
5144
5184
|
}
|
|
5145
5185
|
|
|
@@ -5154,7 +5194,7 @@ class Panel {
|
|
|
5154
5194
|
slider.value = value;
|
|
5155
5195
|
slider.addEventListener( "input", function( e ) {
|
|
5156
5196
|
let new_value = +this.valueAsNumber;
|
|
5157
|
-
vecinput.value = (
|
|
5197
|
+
vecinput.value = round( new_value, options.precision );
|
|
5158
5198
|
Panel._dispatch_event( vecinput, "change" );
|
|
5159
5199
|
}, false );
|
|
5160
5200
|
box.appendChild( slider );
|
|
@@ -5170,7 +5210,7 @@ class Panel {
|
|
|
5170
5210
|
if( e.shiftKey ) mult *= 10;
|
|
5171
5211
|
else if( e.altKey ) mult *= 0.1;
|
|
5172
5212
|
let new_value = ( +this.valueAsNumber - mult * ( e.deltaY > 0 ? 1 : -1 ) );
|
|
5173
|
-
this.value = (
|
|
5213
|
+
this.value = round( new_value, options.precision );
|
|
5174
5214
|
Panel._dispatch_event(vecinput, "change");
|
|
5175
5215
|
}, { passive: false });
|
|
5176
5216
|
|
|
@@ -5183,12 +5223,20 @@ class Panel {
|
|
|
5183
5223
|
|
|
5184
5224
|
let val = e.target.value = clamp( +e.target.valueAsNumber, +vecinput.min, +vecinput.max );
|
|
5185
5225
|
val = options.precision ? round( val, options.precision ) : val;
|
|
5186
|
-
|
|
5226
|
+
|
|
5227
|
+
// Update slider!
|
|
5187
5228
|
if( box.querySelector( ".lexinputslider" ) )
|
|
5229
|
+
{
|
|
5188
5230
|
box.querySelector( ".lexinputslider" ).value = val;
|
|
5231
|
+
}
|
|
5189
5232
|
|
|
5190
5233
|
vecinput.value = val;
|
|
5191
5234
|
|
|
5235
|
+
if( options.units )
|
|
5236
|
+
{
|
|
5237
|
+
vecinput.unitSpan.style.left = measureRealWidth( vecinput.value ) + "px";
|
|
5238
|
+
}
|
|
5239
|
+
|
|
5192
5240
|
// Reset button (default value)
|
|
5193
5241
|
if( !skipCallback )
|
|
5194
5242
|
{
|
|
@@ -5213,7 +5261,7 @@ class Panel {
|
|
|
5213
5261
|
lastY = e.pageY;
|
|
5214
5262
|
document.body.classList.add('nocursor');
|
|
5215
5263
|
document.body.classList.add('noevents');
|
|
5216
|
-
|
|
5264
|
+
dragIcon.classList.remove('hidden');
|
|
5217
5265
|
e.stopImmediatePropagation();
|
|
5218
5266
|
e.stopPropagation();
|
|
5219
5267
|
}
|
|
@@ -5225,8 +5273,8 @@ class Panel {
|
|
|
5225
5273
|
if(e.shiftKey) mult *= 10;
|
|
5226
5274
|
else if(e.altKey) mult *= 0.1;
|
|
5227
5275
|
let new_value = (+vecinput.valueAsNumber + mult * dt);
|
|
5228
|
-
vecinput.value = (+new_value).toFixed(4).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/,'$1');
|
|
5229
|
-
Panel._dispatch_event(vecinput, "change");
|
|
5276
|
+
vecinput.value = (+new_value).toFixed( 4 ).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/,'$1');
|
|
5277
|
+
Panel._dispatch_event( vecinput, "change" );
|
|
5230
5278
|
}
|
|
5231
5279
|
|
|
5232
5280
|
lastY = e.pageY;
|
|
@@ -5240,7 +5288,7 @@ class Panel {
|
|
|
5240
5288
|
doc.removeEventListener("mouseup",inner_mouseup);
|
|
5241
5289
|
document.body.classList.remove('nocursor');
|
|
5242
5290
|
document.body.classList.remove('noevents');
|
|
5243
|
-
|
|
5291
|
+
dragIcon.classList.add('hidden');
|
|
5244
5292
|
}
|
|
5245
5293
|
|
|
5246
5294
|
container.appendChild(box);
|
|
@@ -5277,9 +5325,15 @@ class Panel {
|
|
|
5277
5325
|
};
|
|
5278
5326
|
widget.onSetValue = ( newValue, skipCallback ) => {
|
|
5279
5327
|
const inputs = element.querySelectorAll( ".vecinput" );
|
|
5328
|
+
if( inputs.length == newValue.length )
|
|
5329
|
+
{
|
|
5330
|
+
console.error( "Input length does not match vector length." );
|
|
5331
|
+
return;
|
|
5332
|
+
}
|
|
5333
|
+
|
|
5280
5334
|
for( var i = 0; i < inputs.length; ++i ) {
|
|
5281
5335
|
let value = newValue[ i ];
|
|
5282
|
-
inputs[ i ].value = value ?? 0;
|
|
5336
|
+
inputs[ i ].value = round( value, options.precision ) ?? 0;
|
|
5283
5337
|
Panel._dispatch_event( inputs[ i ], "change", skipCallback );
|
|
5284
5338
|
}
|
|
5285
5339
|
};
|
|
@@ -5319,14 +5373,14 @@ class Panel {
|
|
|
5319
5373
|
if( value[ i ].constructor == Number )
|
|
5320
5374
|
{
|
|
5321
5375
|
value[ i ] = clamp(value[ i ], +vecinput.min, +vecinput.max);
|
|
5322
|
-
value[ i ] =
|
|
5376
|
+
value[ i ] = round( value[ i ], options.precision );
|
|
5323
5377
|
}
|
|
5324
5378
|
|
|
5325
5379
|
vecinput.value = vecinput.iValue = value[ i ];
|
|
5326
5380
|
|
|
5327
|
-
let
|
|
5328
|
-
|
|
5329
|
-
box.appendChild(
|
|
5381
|
+
let dragIcon = document.createElement( 'a' );
|
|
5382
|
+
dragIcon.className = "fa-solid fa-arrows-up-down drag-icon hidden";
|
|
5383
|
+
box.appendChild( dragIcon );
|
|
5330
5384
|
|
|
5331
5385
|
if( options.disabled ) {
|
|
5332
5386
|
vecinput.disabled = true;
|
|
@@ -5342,14 +5396,17 @@ class Panel {
|
|
|
5342
5396
|
if( e.shiftKey ) mult = 10;
|
|
5343
5397
|
else if( e.altKey ) mult = 0.1;
|
|
5344
5398
|
|
|
5345
|
-
if(
|
|
5399
|
+
if( locker.locked )
|
|
5346
5400
|
{
|
|
5347
|
-
for( let v of element.querySelectorAll(".vecinput") )
|
|
5348
|
-
|
|
5401
|
+
for( let v of element.querySelectorAll(".vecinput") )
|
|
5402
|
+
{
|
|
5403
|
+
v.value = round( +v.valueAsNumber - mult * ( e.deltaY > 0 ? 1 : -1 ), options.precision );
|
|
5349
5404
|
Panel._dispatch_event(v, "change");
|
|
5350
5405
|
}
|
|
5351
|
-
}
|
|
5352
|
-
|
|
5406
|
+
}
|
|
5407
|
+
else
|
|
5408
|
+
{
|
|
5409
|
+
this.value = round( +this.valueAsNumber - mult * ( e.deltaY > 0 ? 1 : -1 ), options.precision );
|
|
5353
5410
|
Panel._dispatch_event( vecinput, "change" );
|
|
5354
5411
|
}
|
|
5355
5412
|
}, { passive: false } );
|
|
@@ -5362,7 +5419,7 @@ class Panel {
|
|
|
5362
5419
|
const skipCallback = e.detail;
|
|
5363
5420
|
|
|
5364
5421
|
let val = e.target.value = clamp( e.target.value, +vecinput.min, +vecinput.max );
|
|
5365
|
-
val =
|
|
5422
|
+
val = round( val, options.precision );
|
|
5366
5423
|
|
|
5367
5424
|
// Reset button (default value)
|
|
5368
5425
|
if( !skipCallback )
|
|
@@ -5371,7 +5428,7 @@ class Panel {
|
|
|
5371
5428
|
if( btn ) btn.style.display = val != vecinput.iValue ? "block": "none";
|
|
5372
5429
|
}
|
|
5373
5430
|
|
|
5374
|
-
if(
|
|
5431
|
+
if( locker.locked )
|
|
5375
5432
|
{
|
|
5376
5433
|
for( let v of element.querySelectorAll( ".vecinput" ) ) {
|
|
5377
5434
|
v.value = val;
|
|
@@ -5399,7 +5456,7 @@ class Panel {
|
|
|
5399
5456
|
lastY = e.pageY;
|
|
5400
5457
|
document.body.classList.add('nocursor');
|
|
5401
5458
|
document.body.classList.add('noevents');
|
|
5402
|
-
|
|
5459
|
+
dragIcon.classList.remove('hidden');
|
|
5403
5460
|
e.stopImmediatePropagation();
|
|
5404
5461
|
e.stopPropagation();
|
|
5405
5462
|
}
|
|
@@ -5411,14 +5468,14 @@ class Panel {
|
|
|
5411
5468
|
if(e.shiftKey) mult = 10;
|
|
5412
5469
|
else if(e.altKey) mult = 0.1;
|
|
5413
5470
|
|
|
5414
|
-
if(
|
|
5471
|
+
if( locker.locked )
|
|
5415
5472
|
{
|
|
5416
5473
|
for( let v of element.querySelectorAll(".vecinput") ) {
|
|
5417
|
-
v.value = (+v.valueAsNumber + mult * dt
|
|
5474
|
+
v.value = round( +v.valueAsNumber + mult * dt, options.precision );
|
|
5418
5475
|
Panel._dispatch_event(v, "change");
|
|
5419
5476
|
}
|
|
5420
5477
|
} else {
|
|
5421
|
-
vecinput.value = (+vecinput.valueAsNumber + mult * dt
|
|
5478
|
+
vecinput.value = round( +vecinput.valueAsNumber + mult * dt, options.precision );
|
|
5422
5479
|
Panel._dispatch_event(vecinput, "change");
|
|
5423
5480
|
}
|
|
5424
5481
|
}
|
|
@@ -5428,23 +5485,23 @@ class Panel {
|
|
|
5428
5485
|
e.preventDefault();
|
|
5429
5486
|
}
|
|
5430
5487
|
|
|
5431
|
-
function inner_mouseup(e) {
|
|
5488
|
+
function inner_mouseup( e ) {
|
|
5432
5489
|
var doc = that.root.ownerDocument;
|
|
5433
5490
|
doc.removeEventListener("mousemove",inner_mousemove);
|
|
5434
5491
|
doc.removeEventListener("mouseup",inner_mouseup);
|
|
5435
5492
|
document.body.classList.remove('nocursor');
|
|
5436
5493
|
document.body.classList.remove('noevents');
|
|
5437
|
-
|
|
5494
|
+
dragIcon.classList.add('hidden');
|
|
5438
5495
|
}
|
|
5439
5496
|
|
|
5440
|
-
box.appendChild(vecinput);
|
|
5441
|
-
container.appendChild(box);
|
|
5497
|
+
box.appendChild( vecinput );
|
|
5498
|
+
container.appendChild( box );
|
|
5442
5499
|
}
|
|
5443
5500
|
|
|
5444
|
-
let
|
|
5445
|
-
|
|
5446
|
-
container.appendChild(
|
|
5447
|
-
|
|
5501
|
+
let locker = document.createElement('a');
|
|
5502
|
+
locker.className = "fa-solid fa-lock-open lexicon";
|
|
5503
|
+
container.appendChild(locker);
|
|
5504
|
+
locker.addEventListener("click", function(e) {
|
|
5448
5505
|
this.locked = !this.locked;
|
|
5449
5506
|
if(this.locked){
|
|
5450
5507
|
this.classList.add("fa-lock");
|
|
@@ -5455,7 +5512,7 @@ class Panel {
|
|
|
5455
5512
|
}
|
|
5456
5513
|
}, false);
|
|
5457
5514
|
|
|
5458
|
-
element.appendChild(container);
|
|
5515
|
+
element.appendChild( container );
|
|
5459
5516
|
|
|
5460
5517
|
return widget;
|
|
5461
5518
|
}
|
|
@@ -6380,7 +6437,8 @@ class ContextMenu {
|
|
|
6380
6437
|
this.items = [];
|
|
6381
6438
|
this.colors = {};
|
|
6382
6439
|
|
|
6383
|
-
if(title)
|
|
6440
|
+
if( title )
|
|
6441
|
+
{
|
|
6384
6442
|
const item = {};
|
|
6385
6443
|
item[ title ] = [];
|
|
6386
6444
|
item[ 'className' ] = "cmtitle";
|
|
@@ -6395,7 +6453,7 @@ class ContextMenu {
|
|
|
6395
6453
|
|
|
6396
6454
|
if(!useAbsolute)
|
|
6397
6455
|
{
|
|
6398
|
-
let width = rect.width
|
|
6456
|
+
let width = rect.width;
|
|
6399
6457
|
if(window.innerWidth - rect.right < 0)
|
|
6400
6458
|
div.style.left = (window.innerWidth - width - margin) + "px";
|
|
6401
6459
|
|
|
@@ -6436,7 +6494,6 @@ class ContextMenu {
|
|
|
6436
6494
|
contextmenu.style.marginTop = 3.5 - c.offsetHeight + "px";
|
|
6437
6495
|
|
|
6438
6496
|
// Set final width
|
|
6439
|
-
// contextmenu.style.width = contextmenu.offsetWidth + "px";
|
|
6440
6497
|
this._adjust_position( contextmenu, 6, true );
|
|
6441
6498
|
}
|
|
6442
6499
|
|
|
@@ -6510,7 +6567,7 @@ class ContextMenu {
|
|
|
6510
6567
|
}
|
|
6511
6568
|
|
|
6512
6569
|
onCreate() {
|
|
6513
|
-
this._adjust_position( this.root, 6 );
|
|
6570
|
+
doAsync( () => this._adjust_position( this.root, 6 ) );
|
|
6514
6571
|
}
|
|
6515
6572
|
|
|
6516
6573
|
add( path, options = {} ) {
|
|
@@ -6615,10 +6672,12 @@ LX.ContextMenu = ContextMenu;
|
|
|
6615
6672
|
function addContextMenu( title, event, callback, options )
|
|
6616
6673
|
{
|
|
6617
6674
|
var menu = new ContextMenu( event, title, options );
|
|
6618
|
-
LX.root.appendChild(menu.root);
|
|
6675
|
+
LX.root.appendChild( menu.root );
|
|
6619
6676
|
|
|
6620
|
-
if(callback)
|
|
6677
|
+
if( callback )
|
|
6678
|
+
{
|
|
6621
6679
|
callback( menu );
|
|
6680
|
+
}
|
|
6622
6681
|
|
|
6623
6682
|
menu.onCreate();
|
|
6624
6683
|
|
package/changelog.md
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
# lexgui.js changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.37
|
|
3
|
+
## 0.1.37
|
|
4
4
|
|
|
5
|
+
Audio:
|
|
6
|
+
- Start new audio widgets (Knob wip).
|
|
5
7
|
|
|
8
|
+
Timeline:
|
|
9
|
+
- Major refactor of Timeline
|
|
10
|
+
- Fixed examples
|
|
11
|
+
|
|
12
|
+
Allow unit labels for Number widgets.
|
|
13
|
+
Fixed Number/Vector precision.
|
|
14
|
+
Fixed ContextMenu position on creation over window size.
|
|
15
|
+
Minor bug fixes.
|
|
6
16
|
|
|
7
17
|
## 0.1.36 (master)
|
|
8
18
|
|
package/demo.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { LX } from 'lexgui';
|
|
2
2
|
import 'lexgui/components/codeeditor.js';
|
|
3
3
|
import 'lexgui/components/timeline.js';
|
|
4
|
+
import 'lexgui/components/audio.js';
|
|
4
5
|
|
|
5
6
|
window.LX = LX;
|
|
6
7
|
|
|
@@ -477,6 +478,7 @@ function fillPanel( panel ) {
|
|
|
477
478
|
panel.branch("Preferences", {icon: "fa-solid fa-gear"});
|
|
478
479
|
panel.addButton(null, "Click me, Im Full Width...");
|
|
479
480
|
panel.addText("Text", "Warning text", null, { warning: true });
|
|
481
|
+
panel.addKnob("A Knob", 4, 0, 200, value => { console.log(value) }, /*{ size: 'sm' }*/);
|
|
480
482
|
panel.sameLine(2);
|
|
481
483
|
panel.addFile("Img1", data => { console.log(data) }, {} );
|
|
482
484
|
panel.addFile("Img2", data => { console.log(data) }, {} );
|
|
@@ -547,7 +549,7 @@ function fillPanel( panel ) {
|
|
|
547
549
|
});
|
|
548
550
|
panel.addNumber("Font Size", 36, (value, event) => {
|
|
549
551
|
console.log(value);
|
|
550
|
-
}, { min: 1, max: 48, step: 1});
|
|
552
|
+
}, { min: 1, max: 48, step: 1, units: "px"});
|
|
551
553
|
panel.addVector2("2D Position", [250, 350], (value, event) => {
|
|
552
554
|
console.log(value);
|
|
553
555
|
}, { min: 0, max: 1024 });
|
package/examples/timeline.html
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<script type="module">
|
|
19
19
|
|
|
20
20
|
import { LX } from 'lexgui';
|
|
21
|
-
import { Timeline, KeyFramesTimeline, ClipsTimeline, CurvesTimeline
|
|
21
|
+
import { Timeline, KeyFramesTimeline, ClipsTimeline, CurvesTimeline } from 'lexgui/components/timeline.js';
|
|
22
22
|
|
|
23
23
|
// init library and get main area
|
|
24
24
|
let area = LX.init();
|
|
@@ -123,8 +123,16 @@
|
|
|
123
123
|
console.log(value);
|
|
124
124
|
}, { min: 1, max: 48, step: 1});
|
|
125
125
|
panel.addVector2("2D Position", position, (value, event) => {
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
let currentSelection = activeTimeline.lastKeyFramesSelected[0];
|
|
127
|
+
if( currentSelection ){
|
|
128
|
+
const track = activeTimeline.animationClip.tracks[0];
|
|
129
|
+
const keyframe = currentSelection[2];
|
|
130
|
+
const dim = track.dim;
|
|
131
|
+
|
|
132
|
+
track.values[keyframe * track.dim] = value[0];
|
|
133
|
+
track.values[keyframe * track.dim + 1] = value[1];
|
|
134
|
+
track.edited[keyframe] = true;
|
|
135
|
+
}
|
|
128
136
|
}, { min: 0, max: 1024 });
|
|
129
137
|
panel.branch_open = true;
|
|
130
138
|
panel.merge();
|
|
@@ -177,7 +185,7 @@
|
|
|
177
185
|
keyframesPanel.onresize = () => {
|
|
178
186
|
kfTimeline.resize();
|
|
179
187
|
}
|
|
180
|
-
let kfTimeline = new LX.KeyFramesTimeline('', {
|
|
188
|
+
let kfTimeline = new LX.KeyFramesTimeline('keyframesTimeline', {
|
|
181
189
|
disableNewTracks: true,
|
|
182
190
|
onBeforeCreateTopBar: (panel) => {
|
|
183
191
|
panel.addDropdown("Animation", ["Anim 1", "Anim 2", "Anim 3"], "Anim 1", ()=> {})
|
|
@@ -189,13 +197,13 @@
|
|
|
189
197
|
});
|
|
190
198
|
|
|
191
199
|
keyframesPanel.attach(kfTimeline.root);
|
|
200
|
+
kfTimeline.setAnimationClip({tracks: [{name: "Font.position", values: [250, 450, 250, 250, 250, 450], times: [0, 0.5, 1.0]}, {name: "Item 1.scale", values: [0,1,0, 0.5], times: [0, 0.1, 0.2, 0.3]}, {name: "Item 2", values: [0,1,0,1], times: [0.1]}, {name: "Item 3.position", values: [0,1,0,0,0,0], times: [0.1, 0.2, 0.3]}, {name: "Item 3.scale", values: [0,1,0], times: [ 0.1, 0.2, 0.3]}], duration: 1});
|
|
192
201
|
kfTimeline.setSelectedItems(["Font", "Item 2", "Item 3"]);
|
|
193
|
-
kfTimeline.setAnimationClip({tracks: [{name: "Font.position", values: [250, 350, 250, 250, 250, 350], times: [0, 0.1, 0.2]}, {name: "Item 1.scale", values: [0,1,0, 0.5], times: [0, 0.1, 0.2, 0.3]}, {name: "Item 2", values: [0,1,0,1], times: [0.1]}, {name: "Item 3.position", values: [0,1,0,0,0,0], times: [0.1, 0.2, 0.3]}, {name: "Item 3.scale", values: [0,1,0], times: [ 0.1, 0.2, 0.3]}], duration: 1});
|
|
194
202
|
activeTimeline = kfTimeline;
|
|
195
203
|
kfTimeline.show();
|
|
196
204
|
|
|
197
205
|
|
|
198
|
-
kfTimeline.onSelectKeyFrame = (data, currentSelection
|
|
206
|
+
kfTimeline.onSelectKeyFrame = (data, currentSelection) => {
|
|
199
207
|
if(data.multipleSelection) {
|
|
200
208
|
rightArea.hide();
|
|
201
209
|
return;
|
|
@@ -209,6 +217,8 @@
|
|
|
209
217
|
let values = kfTimeline.animationClip.tracks[id].values;
|
|
210
218
|
const dim = kfTimeline.animationClip.tracks[id].dim;
|
|
211
219
|
|
|
220
|
+
//currentSelection == [track.name, track.idx, frameIdx, track.clipIdx, track.times[frameIdx]]
|
|
221
|
+
const keyFrameIndex = currentSelection[2];
|
|
212
222
|
position = values.slice(keyFrameIndex * dim, keyFrameIndex * dim + dim);
|
|
213
223
|
fillPanel(panel);
|
|
214
224
|
//kfTimeline.animationClip.tracks[currentSelection[0][0]];
|
|
@@ -216,21 +226,23 @@
|
|
|
216
226
|
|
|
217
227
|
kfTimeline.onSetTime = ( time ) => {
|
|
218
228
|
rightArea.show();
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
let
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
valueX = valueX * (1 - t) + values[keyframe * 2 + sign] * t;
|
|
230
|
-
valueY = valueY * (1 - t) + values[keyframe * 2 + sign + 1] * t;
|
|
229
|
+
const keyframe = kfTimeline.getNearestKeyFrame( kfTimeline.animationClip.tracks[0], time, -1);
|
|
230
|
+
if(keyframe != -1) {
|
|
231
|
+
const trackLength = kfTimeline.animationClip.tracks[0].times.length;
|
|
232
|
+
const nextKeyframe = keyframe < (trackLength-1) ? (keyframe + 1) : keyframe;
|
|
233
|
+
const frametime = kfTimeline.animationClip.tracks[0].times[keyframe];
|
|
234
|
+
const nextframeTime = kfTimeline.animationClip.tracks[0].times[nextKeyframe];
|
|
235
|
+
|
|
236
|
+
let t = 1;
|
|
237
|
+
if ( keyframe < trackLength-1){
|
|
238
|
+
t = (time - frametime) / (nextframeTime - frametime);
|
|
231
239
|
}
|
|
240
|
+
|
|
241
|
+
let values = kfTimeline.animationClip.tracks[0].values;
|
|
242
|
+
let valueX = values[keyframe * 2] * (1-t) + t * values[nextKeyframe * 2];
|
|
243
|
+
let valueY = values[keyframe * 2 + 1] * (1-t) + t * values[nextKeyframe * 2 + 1];
|
|
244
|
+
position = [valueX, valueY];
|
|
232
245
|
}
|
|
233
|
-
position = [valueX, valueY];
|
|
234
246
|
fillPanel( panel );
|
|
235
247
|
}
|
|
236
248
|
}
|
|
@@ -282,10 +294,10 @@
|
|
|
282
294
|
|
|
283
295
|
}});
|
|
284
296
|
|
|
285
|
-
let curvesTimeline = new LX.
|
|
297
|
+
let curvesTimeline = new LX.CurvesTimeline("curves-timeline", { range: [-1,1]});
|
|
286
298
|
curvesPanel.attach(curvesTimeline.root);
|
|
287
|
-
curvesTimeline.setSelectedItems(["Item 1", "Item 2", "Item 3"]);
|
|
288
299
|
curvesTimeline.setAnimationClip({tracks: [{name: "Item 1.position", values: [0,1,0,-1], times: [0, 0.1, 0.2, 0.3]}, {name: "Item 1.scale", values: [0,1,0, 0.5], times: [0, 0.1, 0.2, 0.3]}, {name: "Item 2", values: [0,1,0,1], times: [0.1, 0.2, 0.3, 0.8]}, {name: "Item 3.position", values: [0,0,1], times: [0]}, {name: "Item 3.scale", values: [0,1,0], times: [0, 0.1, 0.3]}], duration: 1});
|
|
300
|
+
curvesTimeline.setSelectedItems(["Item 1", "Item 2", "Item 3"]);
|
|
289
301
|
curvesTimeline.show();
|
|
290
302
|
curvesTimeline.draw(0);
|
|
291
303
|
}
|