lexgui 0.6.8 → 0.6.10
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/build/components/timeline.js +116 -80
- package/build/lexgui.css +31 -6
- package/build/lexgui.js +438 -250
- package/build/lexgui.min.css +1 -1
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +438 -250
- package/build/lexgui.module.min.js +1 -1
- package/changelog.md +42 -1
- package/demo.js +2 -2
- package/examples/all_widgets.html +5 -4
- package/examples/editor.html +28 -21
- package/package.json +3 -2
|
@@ -162,7 +162,7 @@ class Timeline {
|
|
|
162
162
|
const playbtn = header.addButton("playBtn", '', (value, event) => {
|
|
163
163
|
this.changeState();
|
|
164
164
|
}, { buttonClass: "accept", title: "Play", hideName: true, icon: "Play@solid", swap: "Pause@solid" });
|
|
165
|
-
playbtn.
|
|
165
|
+
playbtn.setState(this.playing, true);
|
|
166
166
|
|
|
167
167
|
header.addButton("stopBtn", '', (value, event) => {
|
|
168
168
|
this.setState(false, true); // skip callback of set state
|
|
@@ -972,7 +972,7 @@ class Timeline {
|
|
|
972
972
|
setState(state, skipCallback = false) {
|
|
973
973
|
this.playing = state;
|
|
974
974
|
|
|
975
|
-
this.header.widgets.playBtn.
|
|
975
|
+
this.header.widgets.playBtn.setState(this.playing, true);
|
|
976
976
|
|
|
977
977
|
if(this.onStateChange && !skipCallback) {
|
|
978
978
|
this.onStateChange(this.playing);
|
|
@@ -1290,7 +1290,7 @@ class Timeline {
|
|
|
1290
1290
|
* @param {obj} options set some values for the track instance (groups and trackIdx not included)
|
|
1291
1291
|
* @returns
|
|
1292
1292
|
*/
|
|
1293
|
-
instantiateTrack(options = {}) {
|
|
1293
|
+
instantiateTrack(options = {}, clone = false) {
|
|
1294
1294
|
return {
|
|
1295
1295
|
isTrack: true,
|
|
1296
1296
|
id: options.id ?? ( Math.floor(performance.now().toString()) + "_" + Math.floor(Math.random() * 0xffff) ), //must be unique, at least inside a group
|
|
@@ -1307,13 +1307,12 @@ class Timeline {
|
|
|
1307
1307
|
* @param {obj} animation data with which to generate an animationClip
|
|
1308
1308
|
* @returns
|
|
1309
1309
|
*/
|
|
1310
|
-
instantiateAnimationClip(options) {
|
|
1310
|
+
instantiateAnimationClip(options, clone = false) {
|
|
1311
1311
|
options = options ?? {};
|
|
1312
1312
|
const animationClip = {
|
|
1313
1313
|
id: options.id ?? (options.name ?? "animationClip"),
|
|
1314
1314
|
duration: options.duration ?? 0,
|
|
1315
1315
|
tracks: [],
|
|
1316
|
-
tracksPerGroup: options.tracksPerGroup ?? {},
|
|
1317
1316
|
data: options.data ?? null, // user defined data
|
|
1318
1317
|
};
|
|
1319
1318
|
return animationClip;
|
|
@@ -1433,42 +1432,42 @@ class KeyFramesTimeline extends Timeline {
|
|
|
1433
1432
|
* id, dim, values, times, selected, edited, hovered
|
|
1434
1433
|
* @returns
|
|
1435
1434
|
*/
|
|
1436
|
-
instantiateTrack(options ={}){
|
|
1435
|
+
instantiateTrack(options ={}, clone = false){
|
|
1437
1436
|
const track = super.instantiateTrack(options);
|
|
1438
1437
|
track.dim = Math.max(1,options.dim ?? 1); // >= 1
|
|
1439
1438
|
track.groupId = null,
|
|
1440
1439
|
track.groupTrackIdx = -1, // track Idx inside group only if in group
|
|
1441
1440
|
|
|
1442
|
-
track.values = new Float32Array(0);
|
|
1441
|
+
track.values = new Float32Array(0);
|
|
1443
1442
|
track.times = new Float32Array(0);
|
|
1444
1443
|
track.selected = [];
|
|
1445
1444
|
track.edited = [];
|
|
1446
1445
|
track.hovered = [];
|
|
1447
1446
|
|
|
1448
1447
|
if ( options.values && options.times ){
|
|
1449
|
-
track.values = options.values;
|
|
1450
|
-
track.times = options.times;
|
|
1448
|
+
track.values = clone ? options.values.slice() : options.values;
|
|
1449
|
+
track.times = clone ? options.times.slice() : options.times;
|
|
1451
1450
|
|
|
1452
1451
|
const numFrames = track.times.length;
|
|
1453
1452
|
if ( options.selected && options.selected.length == numFrames ){
|
|
1454
|
-
track.selected = options.selected;
|
|
1453
|
+
track.selected = clone ? options.selected.slice() : options.selected;
|
|
1455
1454
|
}else{
|
|
1456
1455
|
track.selected = (new Array(numFrames)).fill(false);
|
|
1457
1456
|
}
|
|
1458
1457
|
if ( options.edited && options.edited.length == numFrames ){
|
|
1459
|
-
track.edited = options.edited;
|
|
1458
|
+
track.edited = clone ? options.edited.slice() : options.edited;
|
|
1460
1459
|
}else{
|
|
1461
1460
|
track.edited = (new Array(numFrames)).fill(false);
|
|
1462
1461
|
}
|
|
1463
1462
|
if ( options.hovered && options.hovered.length == numFrames ){
|
|
1464
|
-
track.hovered = options.hovered;
|
|
1463
|
+
track.hovered = clone ? options.hovered.slice() : options.hovered;
|
|
1465
1464
|
}else{
|
|
1466
1465
|
track.hovered = (new Array(numFrames)).fill(false);
|
|
1467
1466
|
}
|
|
1468
1467
|
}
|
|
1469
1468
|
|
|
1470
1469
|
track.curves = options.curves ?? this.defaultCurves; // only works if dim == 1
|
|
1471
|
-
track.curvesRange = options.curvesRange ?? this.defaultCurvesRange.slice(
|
|
1470
|
+
track.curvesRange = ( options.curvesRange ?? this.defaultCurvesRange ).slice();
|
|
1472
1471
|
return track;
|
|
1473
1472
|
}
|
|
1474
1473
|
|
|
@@ -1477,9 +1476,11 @@ class KeyFramesTimeline extends Timeline {
|
|
|
1477
1476
|
* @param {obj} animation data with which to generate an animationClip
|
|
1478
1477
|
* @returns
|
|
1479
1478
|
*/
|
|
1480
|
-
instantiateAnimationClip(animation) {
|
|
1479
|
+
instantiateAnimationClip(animation, clone = false) {
|
|
1481
1480
|
|
|
1482
|
-
const animationClip = super.instantiateAnimationClip(animation);
|
|
1481
|
+
const animationClip = super.instantiateAnimationClip(animation, clone);
|
|
1482
|
+
|
|
1483
|
+
animationClip.tracksPerGroup = {};
|
|
1483
1484
|
|
|
1484
1485
|
if (animation && animation.tracks) {
|
|
1485
1486
|
const tracksPerGroup = {};
|
|
@@ -1496,18 +1497,13 @@ class KeyFramesTimeline extends Timeline {
|
|
|
1496
1497
|
else{ valueDim = 1; }
|
|
1497
1498
|
}
|
|
1498
1499
|
|
|
1499
|
-
let leftOver = values.length % valueDim; // just in case values have an incorrect length
|
|
1500
|
-
let amounEntries = Math.min( times.length, values.length - leftOver );
|
|
1501
|
-
times = times.slice(0, amounEntries);
|
|
1502
|
-
values = values.slice(0, amounEntries * valueDim);
|
|
1503
|
-
|
|
1504
1500
|
let baseName = track.id ?? track.name;
|
|
1505
1501
|
const [groupId, trackId] = baseName ? this._getValidTrackName(baseName) : [null, null];
|
|
1506
1502
|
|
|
1507
1503
|
const toInstantiate = Object.assign({}, track);
|
|
1508
1504
|
toInstantiate.id = trackId;
|
|
1509
1505
|
toInstantiate.dim = valueDim;
|
|
1510
|
-
const trackInfo = this.instantiateTrack(toInstantiate);
|
|
1506
|
+
const trackInfo = this.instantiateTrack(toInstantiate, clone);
|
|
1511
1507
|
|
|
1512
1508
|
// manual group insertion
|
|
1513
1509
|
if ( groupId ){
|
|
@@ -1525,13 +1521,34 @@ class KeyFramesTimeline extends Timeline {
|
|
|
1525
1521
|
|
|
1526
1522
|
animationClip.tracks.push(trackInfo);
|
|
1527
1523
|
|
|
1528
|
-
if ( times.length ){ duration = Math.max( duration, times[times.length-1]); }
|
|
1524
|
+
if ( trackInfo.times.length ){ duration = Math.max( duration, trackInfo.times[trackInfo.times.length-1]); }
|
|
1529
1525
|
}
|
|
1530
1526
|
|
|
1531
1527
|
animationClip.tracksPerGroup = tracksPerGroup;
|
|
1532
1528
|
if ( !animation || !animation.duration ){
|
|
1533
1529
|
animationClip.duration = duration;
|
|
1534
1530
|
}
|
|
1531
|
+
|
|
1532
|
+
// overwrite trackspergroup
|
|
1533
|
+
if ( animation.tracksPerGroup ){
|
|
1534
|
+
|
|
1535
|
+
// ungroup all tracks (just in case)
|
|
1536
|
+
animationClip.tracks.forEach( (v,i,arr) =>{ v.groupId = null; v.groupTrackIdx = -1; } );
|
|
1537
|
+
|
|
1538
|
+
animationClip.tracksPerGroup = {};
|
|
1539
|
+
let tpg = animation.tracksPerGroup;
|
|
1540
|
+
for( let groupId in tpg ){
|
|
1541
|
+
const source = tpg[groupId];
|
|
1542
|
+
const target = [];
|
|
1543
|
+
for( let ti = 0; ti < source.length; ++ti ){
|
|
1544
|
+
const trackInfo = animationClip.tracks[ source[ti].trackIdx ]; // redo references
|
|
1545
|
+
target[ti] = trackInfo;
|
|
1546
|
+
trackInfo.groupId = groupId;
|
|
1547
|
+
trackInfo.groupTrackIdx = ti; // index of track in group
|
|
1548
|
+
}
|
|
1549
|
+
animationClip.tracksPerGroup[ groupId ] = target;
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1535
1552
|
}
|
|
1536
1553
|
|
|
1537
1554
|
return animationClip;
|
|
@@ -2633,7 +2650,7 @@ class KeyFramesTimeline extends Timeline {
|
|
|
2633
2650
|
*
|
|
2634
2651
|
* @param {int} trackIdx
|
|
2635
2652
|
* @param {array} newValues array of values for each keyframe. It should be a flat array of size track.dim*numKeyframes. Check ADDKEY_VALUESINARRAYS flag
|
|
2636
|
-
* @param {array of numbers} newTimes
|
|
2653
|
+
* @param {array of numbers} newTimes must be ordered ascendently
|
|
2637
2654
|
* @param {number} timeOffset
|
|
2638
2655
|
* @param {int} flags
|
|
2639
2656
|
* KeyFramesTimeline.ADDKEY_VALUESINARRAYS: if set, newValues is an array of arrays, one for each entry [ [1,2,3], [5,6,7] ]. Times is still a flat array of values [ 0, 0.2 ]
|
|
@@ -2656,8 +2673,7 @@ class KeyFramesTimeline extends Timeline {
|
|
|
2656
2673
|
|
|
2657
2674
|
let newIdx = newTimes.length-1;
|
|
2658
2675
|
let oldIdx = trackTimes.length-1;
|
|
2659
|
-
|
|
2660
|
-
let t1 = performance.now();
|
|
2676
|
+
let resultIndices = [];
|
|
2661
2677
|
if ( KeyFramesTimeline.ADDKEY_VALUESINARRAYS & flags ){
|
|
2662
2678
|
|
|
2663
2679
|
for( let i = times.length-1; i > -1; --i ){
|
|
@@ -2672,6 +2688,8 @@ class KeyFramesTimeline extends Timeline {
|
|
|
2672
2688
|
track.hovered.splice(oldIdx+1, 0, false);
|
|
2673
2689
|
track.selected.splice(oldIdx+1, 0, false);
|
|
2674
2690
|
track.edited.splice(oldIdx+1, 0, true);
|
|
2691
|
+
|
|
2692
|
+
resultIndices.push(i);
|
|
2675
2693
|
continue;
|
|
2676
2694
|
}
|
|
2677
2695
|
|
|
@@ -2695,6 +2713,8 @@ class KeyFramesTimeline extends Timeline {
|
|
|
2695
2713
|
track.hovered.splice(oldIdx+1, 0, false);
|
|
2696
2714
|
track.selected.splice(oldIdx+1, 0, false);
|
|
2697
2715
|
track.edited.splice(oldIdx+1, 0, true);
|
|
2716
|
+
|
|
2717
|
+
resultIndices.push(i);
|
|
2698
2718
|
continue;
|
|
2699
2719
|
}
|
|
2700
2720
|
|
|
@@ -2715,8 +2735,11 @@ class KeyFramesTimeline extends Timeline {
|
|
|
2715
2735
|
this.setDuration(newTimes[newTimes.length - 1] + timeOffset);
|
|
2716
2736
|
}
|
|
2717
2737
|
|
|
2718
|
-
if(this.onUpdateTrack)
|
|
2738
|
+
if(this.onUpdateTrack){
|
|
2719
2739
|
this.onUpdateTrack( [trackIdx] );
|
|
2740
|
+
}
|
|
2741
|
+
|
|
2742
|
+
return resultIndices;
|
|
2720
2743
|
}
|
|
2721
2744
|
|
|
2722
2745
|
deleteSelectedContent(skipCallback = false) {
|
|
@@ -3036,6 +3059,10 @@ LX.KeyFramesTimeline = KeyFramesTimeline;
|
|
|
3036
3059
|
*/
|
|
3037
3060
|
|
|
3038
3061
|
class ClipsTimeline extends Timeline {
|
|
3062
|
+
static CLONEREASON_COPY = 1;
|
|
3063
|
+
static CLONEREASON_PASTE = 2;
|
|
3064
|
+
static CLONEREASON_HISTORY = 3;
|
|
3065
|
+
static CLONEREASON_TRACKCLONE = 4;
|
|
3039
3066
|
|
|
3040
3067
|
/**
|
|
3041
3068
|
* @param {string} name
|
|
@@ -3057,14 +3084,14 @@ class ClipsTimeline extends Timeline {
|
|
|
3057
3084
|
* @param {obj} animation data with which to generate an animationClip
|
|
3058
3085
|
* @returns
|
|
3059
3086
|
*/
|
|
3060
|
-
instantiateAnimationClip(animation) {
|
|
3087
|
+
instantiateAnimationClip(animation, clone = false) {
|
|
3061
3088
|
|
|
3062
3089
|
const animationClip = super.instantiateAnimationClip(animation);
|
|
3063
3090
|
|
|
3064
3091
|
if (animation && animation.tracks){
|
|
3065
3092
|
for( let i = 0; i < animation.tracks.length; ++i ) {
|
|
3066
3093
|
|
|
3067
|
-
const trackInfo = this.instantiateTrack( animation.tracks[i] );
|
|
3094
|
+
const trackInfo = this.instantiateTrack( animation.tracks[i], clone );
|
|
3068
3095
|
trackInfo.trackIdx = animationClip.tracks.length;
|
|
3069
3096
|
|
|
3070
3097
|
animationClip.tracks.push(trackInfo);
|
|
@@ -3074,6 +3101,47 @@ class ClipsTimeline extends Timeline {
|
|
|
3074
3101
|
return animationClip;
|
|
3075
3102
|
}
|
|
3076
3103
|
|
|
3104
|
+
/**
|
|
3105
|
+
*
|
|
3106
|
+
* @param {obj} options set some values for the track instance (groups and trackIdx not included)
|
|
3107
|
+
* @returns
|
|
3108
|
+
*/
|
|
3109
|
+
instantiateTrack(options = {}, clone = false) {
|
|
3110
|
+
const track = super.instantiateTrack(options);
|
|
3111
|
+
|
|
3112
|
+
track.trackIdx = this.animationClip.tracks.length;
|
|
3113
|
+
|
|
3114
|
+
track.selected = [];
|
|
3115
|
+
track.edited = [];
|
|
3116
|
+
track.hovered = [];
|
|
3117
|
+
|
|
3118
|
+
if( options.clips ){
|
|
3119
|
+
track.clips = clone ? this.cloneClips(options.clips, 0, ClipsTimeline.CLONEREASON_TRACKCLONE) : options.clips;
|
|
3120
|
+
}else{
|
|
3121
|
+
track.clips = [];
|
|
3122
|
+
}
|
|
3123
|
+
|
|
3124
|
+
const numClips = track.clips.length;
|
|
3125
|
+
|
|
3126
|
+
if ( options.selected && options.selected.length == numClips ){
|
|
3127
|
+
track.selected = clone ? options.selected.slice() : options.selected;
|
|
3128
|
+
}else{
|
|
3129
|
+
track.selected = (new Array(numClips)).fill(false);
|
|
3130
|
+
}
|
|
3131
|
+
if ( options.edited && options.edited.length == numClips ){
|
|
3132
|
+
track.edited = clone ? options.edited.slice() : options.edited;
|
|
3133
|
+
}else{
|
|
3134
|
+
track.edited = (new Array(numClips)).fill(false);
|
|
3135
|
+
}
|
|
3136
|
+
if ( options.hovered && options.hovered.length == numClips ){
|
|
3137
|
+
track.hovered = clone ? options.hovered.slice() : options.hovered;
|
|
3138
|
+
}else{
|
|
3139
|
+
track.hovered = (new Array(numClips)).fill(false);
|
|
3140
|
+
}
|
|
3141
|
+
|
|
3142
|
+
return track;
|
|
3143
|
+
}
|
|
3144
|
+
|
|
3077
3145
|
// use default updateleftpanel
|
|
3078
3146
|
// generateSelectedItemsTreeData(){}
|
|
3079
3147
|
|
|
@@ -3099,6 +3167,7 @@ class ClipsTimeline extends Timeline {
|
|
|
3099
3167
|
setAnimationClip( animation, needsToProcess ){
|
|
3100
3168
|
super.setAnimationClip(animation, needsToProcess);
|
|
3101
3169
|
this.changeSelectedItems();
|
|
3170
|
+
return this.animationClip;
|
|
3102
3171
|
}
|
|
3103
3172
|
|
|
3104
3173
|
// OVERRIDE
|
|
@@ -3121,42 +3190,6 @@ class ClipsTimeline extends Timeline {
|
|
|
3121
3190
|
|
|
3122
3191
|
this.updateLeftPanel();
|
|
3123
3192
|
}
|
|
3124
|
-
|
|
3125
|
-
/**
|
|
3126
|
-
*
|
|
3127
|
-
* @param {obj} options set some values for the track instance (groups and trackIdx not included)
|
|
3128
|
-
* @returns
|
|
3129
|
-
*/
|
|
3130
|
-
instantiateTrack(options = {}) {
|
|
3131
|
-
const track = super.instantiateTrack(options);
|
|
3132
|
-
|
|
3133
|
-
track.trackIdx = this.animationClip.tracks.length;
|
|
3134
|
-
|
|
3135
|
-
track.clips = options.clips ?? [];
|
|
3136
|
-
track.selected = [];
|
|
3137
|
-
track.edited = [];
|
|
3138
|
-
track.hovered = [];
|
|
3139
|
-
|
|
3140
|
-
const numClips = track.clips.length;
|
|
3141
|
-
|
|
3142
|
-
if ( options.selected && options.selected.length == numClips ){
|
|
3143
|
-
track.selected = options.selected;
|
|
3144
|
-
}else{
|
|
3145
|
-
track.selected = (new Array(numClips)).fill(false);
|
|
3146
|
-
}
|
|
3147
|
-
if ( options.edited && options.edited.length == numClips ){
|
|
3148
|
-
track.edited = options.edited;
|
|
3149
|
-
}else{
|
|
3150
|
-
track.edited = (new Array(numClips)).fill(false);
|
|
3151
|
-
}
|
|
3152
|
-
if ( options.hovered && options.hovered.length == numClips ){
|
|
3153
|
-
track.hovered = options.hovered;
|
|
3154
|
-
}else{
|
|
3155
|
-
track.hovered = (new Array(numClips)).fill(false);
|
|
3156
|
-
}
|
|
3157
|
-
|
|
3158
|
-
return track;
|
|
3159
|
-
}
|
|
3160
3193
|
|
|
3161
3194
|
unHoverAll(){
|
|
3162
3195
|
if(this.lastHovered){
|
|
@@ -3229,6 +3262,10 @@ class ClipsTimeline extends Timeline {
|
|
|
3229
3262
|
let localY = e.localY;
|
|
3230
3263
|
let track = e.track;
|
|
3231
3264
|
|
|
3265
|
+
if ( e.button > 0 ){
|
|
3266
|
+
return;
|
|
3267
|
+
}
|
|
3268
|
+
|
|
3232
3269
|
if(e.ctrlKey && track) { // move clips
|
|
3233
3270
|
|
|
3234
3271
|
let x = e.offsetX;
|
|
@@ -3297,10 +3334,10 @@ class ClipsTimeline extends Timeline {
|
|
|
3297
3334
|
const track = this.animationClip.tracks[this.lastClipsSelected[0][0]];
|
|
3298
3335
|
let clip = track.clips[this.lastClipsSelected[0][1]];
|
|
3299
3336
|
if( this.dragClipMode == "fadein" ) {
|
|
3300
|
-
clip.fadein = Math.min(Math.max(clip.fadein + delta, clip.start), clip.fadeout);
|
|
3337
|
+
clip.fadein = Math.min(Math.max(clip.fadein + delta, clip.start), clip.fadeout ?? (clip.start+clip.duration) );
|
|
3301
3338
|
}
|
|
3302
3339
|
else if( this.dragClipMode == "fadeout" ) {
|
|
3303
|
-
clip.fadeout = Math.max(Math.min(clip.fadeout + delta, clip.start+clip.duration), clip.fadein);
|
|
3340
|
+
clip.fadeout = Math.max(Math.min(clip.fadeout + delta, clip.start+clip.duration), clip.fadein ?? clip.start );
|
|
3304
3341
|
}
|
|
3305
3342
|
else if( this.dragClipMode == "duration" ) {
|
|
3306
3343
|
let duration = Math.max(0, clip.duration + delta);
|
|
@@ -3715,7 +3752,7 @@ class ClipsTimeline extends Timeline {
|
|
|
3715
3752
|
const fadeinX = this.pixelsPerSecond * (clip.fadein - clip.start);
|
|
3716
3753
|
ctx.roundRect(x, y + offset, fadeinX, trackHeight, {tl: 5, bl: 5, tr:0, br:0}, true);
|
|
3717
3754
|
}
|
|
3718
|
-
if ( clip.
|
|
3755
|
+
if ( clip.fadeout != undefined ){
|
|
3719
3756
|
const fadeoutX = this.pixelsPerSecond * (clip.start + clip.duration - (clip.fadeout));
|
|
3720
3757
|
ctx.roundRect( x + w - fadeoutX, y + offset, fadeoutX, trackHeight, {tl: 0, bl: 0, tr:5, br:5}, true);
|
|
3721
3758
|
}
|
|
@@ -3741,18 +3778,16 @@ class ClipsTimeline extends Timeline {
|
|
|
3741
3778
|
}
|
|
3742
3779
|
|
|
3743
3780
|
|
|
3744
|
-
|
|
3745
|
-
if( this.pixelsPerSecond < 200) {
|
|
3746
|
-
ctx.font = this.pixelsPerSecond * 0.06 +"px" + Timeline.FONT;
|
|
3747
|
-
}
|
|
3748
|
-
|
|
3749
|
-
const text = clip.id ?? ""; //clip.id.replaceAll("_", " ").replaceAll("-", " ");
|
|
3781
|
+
let text = clip.id ?? ""; //clip.id.replaceAll("_", " ").replaceAll("-", " ");
|
|
3750
3782
|
const textInfo = ctx.measureText( text );
|
|
3751
3783
|
|
|
3752
|
-
|
|
3753
|
-
if(
|
|
3754
|
-
|
|
3784
|
+
let textWidth = textInfo.width;
|
|
3785
|
+
if ( textWidth > w && textWidth > 0){
|
|
3786
|
+
let amount = Math.floor( w * text.length / textWidth );
|
|
3787
|
+
text = text.substr( 0, amount );
|
|
3788
|
+
textWidth = w;
|
|
3755
3789
|
}
|
|
3790
|
+
ctx.fillText( text, x + (w - textWidth)*0.5, y + offset + trackHeight * 0.5);
|
|
3756
3791
|
|
|
3757
3792
|
ctx.fillStyle = track.hovered[j] ? "white" : "#f5f5f5"//track.hovered[j] ? "white" : Timeline.FONT_COLOR_QUATERNARY;
|
|
3758
3793
|
ctx.strokeStyle = "rgba(125,125,125,0.4)";
|
|
@@ -4022,9 +4057,10 @@ class ClipsTimeline extends Timeline {
|
|
|
4022
4057
|
* User defined. Used when copying and pasting
|
|
4023
4058
|
* @param {Array of clips} clipsToClone array of original clips. Do not modify clips in this array
|
|
4024
4059
|
* @param {float} timeOffset Value of time that should be added (or subtracted) from the timing attributes
|
|
4060
|
+
* @param {int} reason Flag to signal the reason of the clone
|
|
4025
4061
|
* @returns {Array of clips}
|
|
4026
4062
|
*/
|
|
4027
|
-
cloneClips( clipsToClone, timeOffset ){
|
|
4063
|
+
cloneClips( clipsToClone, timeOffset, reason = 0 ){
|
|
4028
4064
|
let clipsToReturn = JSON.parse(JSON.stringify(clipsToClone))
|
|
4029
4065
|
for(let i = 0; i < clipsToReturn.length; ++i){
|
|
4030
4066
|
let clip = clipsToReturn[i];
|
|
@@ -4057,7 +4093,7 @@ class ClipsTimeline extends Timeline {
|
|
|
4057
4093
|
}
|
|
4058
4094
|
|
|
4059
4095
|
globalStart = Math.max(0, globalStart);
|
|
4060
|
-
this.clipboard = this.cloneClips( clipsToCopy, -globalStart );
|
|
4096
|
+
this.clipboard = this.cloneClips( clipsToCopy, -globalStart, ClipsTimeline.CLONEREASON_COPY );
|
|
4061
4097
|
}
|
|
4062
4098
|
|
|
4063
4099
|
pasteContent( time = this.currentTime ) {
|
|
@@ -4068,7 +4104,7 @@ class ClipsTimeline extends Timeline {
|
|
|
4068
4104
|
|
|
4069
4105
|
time = Math.max(0, time);
|
|
4070
4106
|
|
|
4071
|
-
let clipsToAdd = this.cloneClips( this.clipboard, time );
|
|
4107
|
+
let clipsToAdd = this.cloneClips( this.clipboard, time, ClipsTimeline.CLONEREASON_PASTE );
|
|
4072
4108
|
this.addClips(clipsToAdd, 0);
|
|
4073
4109
|
}
|
|
4074
4110
|
|
|
@@ -4117,7 +4153,7 @@ class ClipsTimeline extends Timeline {
|
|
|
4117
4153
|
*/
|
|
4118
4154
|
historyGenerateTrackStep( trackIdx ){
|
|
4119
4155
|
const track = this.animationClip.tracks[trackIdx];
|
|
4120
|
-
const clips = this.cloneClips(track.clips, 0);
|
|
4156
|
+
const clips = this.cloneClips(track.clips, 0, ClipsTimeline.CLONEREASON_HISTORY);
|
|
4121
4157
|
|
|
4122
4158
|
const undoStep = {
|
|
4123
4159
|
trackIdx: trackIdx, // already done by saveState
|
package/build/lexgui.css
CHANGED
|
@@ -1889,7 +1889,7 @@ dialog .lexselect .lexselectoptions {
|
|
|
1889
1889
|
|
|
1890
1890
|
.lexselect .lexselectlabel {
|
|
1891
1891
|
width: 100%;
|
|
1892
|
-
color: var(--global-text-
|
|
1892
|
+
color: var(--global-text-tertiary);
|
|
1893
1893
|
padding-inline: 0.6rem;
|
|
1894
1894
|
padding-block: 0.2rem;
|
|
1895
1895
|
min-height: 20px;
|
|
@@ -2966,6 +2966,10 @@ meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
|
|
|
2966
2966
|
font-size: var(--global-font-size-lg);
|
|
2967
2967
|
}
|
|
2968
2968
|
|
|
2969
|
+
.lexmenubar .lexmenubuttons.left {
|
|
2970
|
+
margin-left: unset;
|
|
2971
|
+
}
|
|
2972
|
+
|
|
2969
2973
|
.lexmenubar .lexmenubuttons.right {
|
|
2970
2974
|
margin-left: unset;
|
|
2971
2975
|
margin-right: 12px;
|
|
@@ -3565,6 +3569,20 @@ meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
|
|
|
3565
3569
|
margin-right: 0px;
|
|
3566
3570
|
}
|
|
3567
3571
|
|
|
3572
|
+
.lexoverlayseparator {
|
|
3573
|
+
background-color: var(--global-color-tertiary);
|
|
3574
|
+
opacity: 0.9;
|
|
3575
|
+
width: 2px;
|
|
3576
|
+
height: calc(100% + 0.5em);
|
|
3577
|
+
margin-top: -0.25em;
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3580
|
+
.lexoverlaybuttonscontainer.vertical .lexoverlayseparator {
|
|
3581
|
+
width: calc(100% + 0.5em);
|
|
3582
|
+
height: 2px;
|
|
3583
|
+
margin-left: -0.25em;
|
|
3584
|
+
}
|
|
3585
|
+
|
|
3568
3586
|
/* Area Tabs */
|
|
3569
3587
|
|
|
3570
3588
|
.lexareatabs {
|
|
@@ -3747,9 +3765,9 @@ meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
|
|
|
3747
3765
|
|
|
3748
3766
|
.lexlayers {
|
|
3749
3767
|
display: grid;
|
|
3750
|
-
grid-template-columns:
|
|
3768
|
+
grid-template-columns: repeat(auto-fit, minmax(18px, 1fr));
|
|
3751
3769
|
grid-gap: 6px 8px;
|
|
3752
|
-
|
|
3770
|
+
max-width: calc(26px * 8); /* 8 layers max */
|
|
3753
3771
|
}
|
|
3754
3772
|
|
|
3755
3773
|
.lexlayer {
|
|
@@ -3757,6 +3775,7 @@ meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
|
|
|
3757
3775
|
background-color: var(--layer-color);
|
|
3758
3776
|
color: var(--global-text-primary);
|
|
3759
3777
|
text-align: center;
|
|
3778
|
+
place-self: center;
|
|
3760
3779
|
line-height: 19px;
|
|
3761
3780
|
width: 18px;
|
|
3762
3781
|
height: 18px;
|
|
@@ -3994,6 +4013,11 @@ meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
|
|
|
3994
4013
|
align-content: center;
|
|
3995
4014
|
}
|
|
3996
4015
|
|
|
4016
|
+
.lextable td.empty-row {
|
|
4017
|
+
text-align: center;
|
|
4018
|
+
padding-block: 16px;
|
|
4019
|
+
}
|
|
4020
|
+
|
|
3997
4021
|
.lextable th {
|
|
3998
4022
|
--th-color: var(--global-text-secondary);
|
|
3999
4023
|
font-weight: 600;
|
|
@@ -4101,7 +4125,7 @@ meter:-moz-meter-sub-sub-optimum::-moz-meter-bar {
|
|
|
4101
4125
|
grid-column: span 2;
|
|
4102
4126
|
}
|
|
4103
4127
|
|
|
4104
|
-
.lexcustomcontainer span {
|
|
4128
|
+
.lexcustomcontainer button.custom span {
|
|
4105
4129
|
align-items: center;
|
|
4106
4130
|
display: flex;
|
|
4107
4131
|
justify-content: space-between;
|
|
@@ -4562,9 +4586,10 @@ ul.lexassetscontent {
|
|
|
4562
4586
|
}
|
|
4563
4587
|
|
|
4564
4588
|
.lexassetscontent .lexitemdesc {
|
|
4565
|
-
position:
|
|
4589
|
+
position: fixed;
|
|
4566
4590
|
font-weight: 600;
|
|
4567
|
-
|
|
4591
|
+
white-space: nowrap;
|
|
4592
|
+
background-color: var(--global-text-secondary);
|
|
4568
4593
|
color: var(--global-color-primary);
|
|
4569
4594
|
font-size: var(--global-font-size);
|
|
4570
4595
|
border-radius: 6px;
|