lexgui 8.0.0 → 8.1.1
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 +3 -3
- package/build/components/AlertDialog.d.ts +7 -0
- package/build/components/Counter.d.ts +1 -0
- package/build/components/Dialog.d.ts +1 -1
- package/build/components/Footer.d.ts +1 -1
- package/build/components/Menubar.d.ts +2 -2
- package/build/core/Area.d.ts +22 -22
- package/build/core/Namespace.js +34 -34
- package/build/core/Namespace.js.map +1 -1
- package/build/core/Panel.d.ts +2 -3
- package/build/extensions/AssetView.d.ts +136 -134
- package/build/extensions/AssetView.js +1367 -1320
- package/build/extensions/AssetView.js.map +1 -1
- package/build/extensions/Audio.js +19 -19
- package/build/extensions/Audio.js.map +1 -1
- package/build/extensions/CodeEditor.js +867 -647
- package/build/extensions/CodeEditor.js.map +1 -1
- package/build/extensions/DocMaker.d.ts +1 -1
- package/build/extensions/DocMaker.js +73 -61
- package/build/extensions/DocMaker.js.map +1 -1
- package/build/extensions/GraphEditor.js +406 -305
- package/build/extensions/GraphEditor.js.map +1 -1
- package/build/extensions/ImUi.js +21 -20
- package/build/extensions/ImUi.js.map +1 -1
- package/build/extensions/Timeline.d.ts +29 -36
- package/build/extensions/Timeline.js +421 -424
- package/build/extensions/Timeline.js.map +1 -1
- package/build/extensions/VideoEditor.js +101 -97
- package/build/extensions/VideoEditor.js.map +1 -1
- package/build/extensions/index.d.ts +8 -8
- package/build/extensions/index.js +1 -1
- package/build/index.all.d.ts +2 -2
- package/build/index.css.d.ts +1 -1
- package/build/index.d.ts +56 -55
- package/build/lexgui.all.js +28488 -27640
- package/build/lexgui.all.js.map +1 -1
- package/build/lexgui.all.min.js +1 -1
- package/build/lexgui.all.module.js +28412 -27565
- package/build/lexgui.all.module.js.map +1 -1
- package/build/lexgui.all.module.min.js +1 -1
- package/build/lexgui.css +176 -69
- package/build/lexgui.js +13796 -13330
- package/build/lexgui.js.map +1 -1
- package/build/lexgui.min.css +1 -1
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +13733 -13268
- package/build/lexgui.module.js.map +1 -1
- package/build/lexgui.module.min.js +1 -1
- package/changelog.md +22 -1
- package/demo.js +6 -5
- package/examples/all-components.html +3 -0
- package/examples/asset-view.html +52 -6
- package/examples/dialogs.html +3 -3
- package/examples/editor.html +1 -1
- package/examples/index.html +1 -1
- package/package.json +4 -1
|
@@ -3,7 +3,7 @@ import { LX } from '../core/Namespace.js';
|
|
|
3
3
|
|
|
4
4
|
// VideoEditor.ts @evallsg
|
|
5
5
|
if (!LX) {
|
|
6
|
-
throw (
|
|
6
|
+
throw ('Missing LX namespace!');
|
|
7
7
|
}
|
|
8
8
|
LX.extensions.push('VideoEditor');
|
|
9
9
|
const vec2 = LX.vec2;
|
|
@@ -15,9 +15,9 @@ LX.Panel;
|
|
|
15
15
|
class TimeBar {
|
|
16
16
|
static TIMEBAR_PLAY = 1;
|
|
17
17
|
static TIMEBAR_TRIM = 2;
|
|
18
|
-
static BACKGROUND_COLOR = LX.getThemeColor(
|
|
19
|
-
static COLOR = LX.getThemeColor(
|
|
20
|
-
static ACTIVE_COLOR =
|
|
18
|
+
static BACKGROUND_COLOR = LX.getThemeColor('global-branch-darker');
|
|
19
|
+
static COLOR = LX.getThemeColor('global-button-color');
|
|
20
|
+
static ACTIVE_COLOR = '#668ee4';
|
|
21
21
|
type = TimeBar.TIMEBAR_PLAY;
|
|
22
22
|
duration = 1.0;
|
|
23
23
|
canvas;
|
|
@@ -46,7 +46,7 @@ class TimeBar {
|
|
|
46
46
|
this.canvas.width = area.size[0];
|
|
47
47
|
this.canvas.height = area.size[1];
|
|
48
48
|
area.attach(this.canvas);
|
|
49
|
-
this.ctx = this.canvas.getContext(
|
|
49
|
+
this.ctx = this.canvas.getContext('2d');
|
|
50
50
|
this.markerWidth = options.markerWidth ?? this.markerWidth;
|
|
51
51
|
this.markerHeight = options.markerHeight ?? (this.canvas.height * 0.5);
|
|
52
52
|
this.offset = options.offset || (this.markerWidth * 0.5 + 5);
|
|
@@ -59,7 +59,7 @@ class TimeBar {
|
|
|
59
59
|
this.currentX = this.startX;
|
|
60
60
|
this._draw();
|
|
61
61
|
this.updateTheme();
|
|
62
|
-
LX.addSignal(
|
|
62
|
+
LX.addSignal('@on_new_color_scheme', () => {
|
|
63
63
|
// Retrieve again the color using LX.getThemeColor, which checks the applied theme
|
|
64
64
|
this.updateTheme();
|
|
65
65
|
});
|
|
@@ -68,9 +68,9 @@ class TimeBar {
|
|
|
68
68
|
this.canvas.onmouseup = (e) => this.onMouseUp(e);
|
|
69
69
|
}
|
|
70
70
|
updateTheme() {
|
|
71
|
-
TimeBar.BACKGROUND_COLOR = LX.getThemeColor(
|
|
72
|
-
TimeBar.COLOR = LX.getThemeColor(
|
|
73
|
-
TimeBar.ACTIVE_COLOR =
|
|
71
|
+
TimeBar.BACKGROUND_COLOR = LX.getThemeColor('global-color-secondary');
|
|
72
|
+
TimeBar.COLOR = LX.getThemeColor('global-color-quaternary');
|
|
73
|
+
TimeBar.ACTIVE_COLOR = '#668ee4';
|
|
74
74
|
}
|
|
75
75
|
setDuration(duration) {
|
|
76
76
|
this.duration = duration;
|
|
@@ -132,7 +132,8 @@ class TimeBar {
|
|
|
132
132
|
// Min-Max time markers
|
|
133
133
|
this._drawTrimMarker('start', this.startX, { color: null, fillColor: TimeBar.ACTIVE_COLOR || '#5f88c9' });
|
|
134
134
|
this._drawTrimMarker('end', this.endX, { color: null, fillColor: TimeBar.ACTIVE_COLOR || '#5f88c9' });
|
|
135
|
-
this._drawTimeMarker('current', this.currentX, { color: '#e5e5e5',
|
|
135
|
+
this._drawTimeMarker('current', this.currentX, { color: '#e5e5e5',
|
|
136
|
+
fillColor: TimeBar.ACTIVE_COLOR || '#5f88c9', width: this.markerWidth });
|
|
136
137
|
if (this.onDraw) {
|
|
137
138
|
this.onDraw();
|
|
138
139
|
}
|
|
@@ -146,7 +147,7 @@ class TimeBar {
|
|
|
146
147
|
return;
|
|
147
148
|
// Shadow
|
|
148
149
|
if (this.hovering == name) {
|
|
149
|
-
ctx.shadowColor =
|
|
150
|
+
ctx.shadowColor = 'white';
|
|
150
151
|
ctx.shadowBlur = 2;
|
|
151
152
|
}
|
|
152
153
|
ctx.globalAlpha = 1;
|
|
@@ -155,7 +156,7 @@ class TimeBar {
|
|
|
155
156
|
ctx.roundRect(x - w * 0.5, y, w, h, 2);
|
|
156
157
|
ctx.fill();
|
|
157
158
|
ctx.fillStyle = ctx.strokeStyle = options.fillColor || '#111'; // "#FFF";
|
|
158
|
-
ctx.strokeStyle =
|
|
159
|
+
ctx.strokeStyle = 'white';
|
|
159
160
|
ctx.beginPath();
|
|
160
161
|
ctx.lineWidth = 2;
|
|
161
162
|
ctx.moveTo(x, y + 4);
|
|
@@ -174,11 +175,11 @@ class TimeBar {
|
|
|
174
175
|
ctx.fillStyle = ctx.strokeStyle = options.fillColor || '#111'; // "#FFF";
|
|
175
176
|
// Shadow
|
|
176
177
|
if (this.hovering == name) {
|
|
177
|
-
ctx.shadowColor =
|
|
178
|
+
ctx.shadowColor = 'white';
|
|
178
179
|
ctx.shadowBlur = 2;
|
|
179
180
|
}
|
|
180
181
|
// Current time line
|
|
181
|
-
ctx.fillStyle = ctx.strokeStyle =
|
|
182
|
+
ctx.fillStyle = ctx.strokeStyle = 'white';
|
|
182
183
|
ctx.beginPath();
|
|
183
184
|
ctx.moveTo(x, y);
|
|
184
185
|
ctx.lineTo(x, y + h * 0.5);
|
|
@@ -214,15 +215,15 @@ class TimeBar {
|
|
|
214
215
|
// grab trim markers only from the bottom
|
|
215
216
|
if (Math.abs(this.startX - x) < threshold && this.position.y < y) {
|
|
216
217
|
this.dragging = 'start';
|
|
217
|
-
canvas.style.cursor =
|
|
218
|
+
canvas.style.cursor = 'grabbing';
|
|
218
219
|
}
|
|
219
220
|
else if (Math.abs(this.endX - x) < threshold && this.position.y < y) {
|
|
220
221
|
this.dragging = 'end';
|
|
221
|
-
canvas.style.cursor =
|
|
222
|
+
canvas.style.cursor = 'grabbing';
|
|
222
223
|
}
|
|
223
224
|
else {
|
|
224
225
|
this.dragging = 'current';
|
|
225
|
-
canvas.style.cursor =
|
|
226
|
+
canvas.style.cursor = 'grabbing';
|
|
226
227
|
if (x < this.startX) {
|
|
227
228
|
this.currentX = this.startX;
|
|
228
229
|
}
|
|
@@ -247,7 +248,7 @@ class TimeBar {
|
|
|
247
248
|
return;
|
|
248
249
|
}
|
|
249
250
|
const canvas = this.canvas;
|
|
250
|
-
canvas.style.cursor =
|
|
251
|
+
canvas.style.cursor = 'default';
|
|
251
252
|
}
|
|
252
253
|
onMouseMove(e) {
|
|
253
254
|
if (this.onMouse) {
|
|
@@ -283,19 +284,19 @@ class TimeBar {
|
|
|
283
284
|
const threshold = this.markerWidth * 0.5;
|
|
284
285
|
if (Math.abs(this.startX - x) < threshold) {
|
|
285
286
|
this.hovering = 'start';
|
|
286
|
-
canvas.style.cursor =
|
|
287
|
+
canvas.style.cursor = 'grab';
|
|
287
288
|
}
|
|
288
289
|
else if (Math.abs(this.endX - x) < threshold) {
|
|
289
290
|
this.hovering = 'end';
|
|
290
|
-
canvas.style.cursor =
|
|
291
|
+
canvas.style.cursor = 'grab';
|
|
291
292
|
}
|
|
292
293
|
else if (Math.abs(this.currentX - x) < threshold) {
|
|
293
294
|
this.hovering = 'current';
|
|
294
|
-
canvas.style.cursor =
|
|
295
|
+
canvas.style.cursor = 'grab';
|
|
295
296
|
}
|
|
296
297
|
else {
|
|
297
298
|
delete this.hovering;
|
|
298
|
-
canvas.style.cursor =
|
|
299
|
+
canvas.style.cursor = 'default';
|
|
299
300
|
}
|
|
300
301
|
}
|
|
301
302
|
this._draw();
|
|
@@ -332,8 +333,8 @@ class VideoEditor {
|
|
|
332
333
|
playing = false;
|
|
333
334
|
videoReady = false;
|
|
334
335
|
controls = true;
|
|
335
|
-
startTimeString =
|
|
336
|
-
endTimeString =
|
|
336
|
+
startTimeString = '0:0';
|
|
337
|
+
endTimeString = '0:0';
|
|
337
338
|
speed = 1.0;
|
|
338
339
|
currentTime = 0.0;
|
|
339
340
|
startTime = 0.0;
|
|
@@ -346,7 +347,7 @@ class VideoEditor {
|
|
|
346
347
|
crop = false;
|
|
347
348
|
dragOffsetX = 0.0;
|
|
348
349
|
dragOffsetY = 0.0;
|
|
349
|
-
currentTimeString =
|
|
350
|
+
currentTimeString = '';
|
|
350
351
|
timebar;
|
|
351
352
|
mainArea;
|
|
352
353
|
cropArea; // HTMLElement with normCoord attribute;
|
|
@@ -378,12 +379,13 @@ class VideoEditor {
|
|
|
378
379
|
controlsArea = options.controlsArea;
|
|
379
380
|
}
|
|
380
381
|
else {
|
|
381
|
-
[videoArea, controlsArea] = area.split({ type: 'vertical', sizes: [
|
|
382
|
+
[videoArea, controlsArea] = area.split({ type: 'vertical', sizes: ['85%', null], minimizable: false,
|
|
383
|
+
resize: false });
|
|
382
384
|
}
|
|
383
385
|
controlsArea.root.classList.add('lexconstrolsarea');
|
|
384
|
-
this.cropArea = document.createElement(
|
|
385
|
-
this.cropArea.id =
|
|
386
|
-
this.cropArea.className =
|
|
386
|
+
this.cropArea = document.createElement('div');
|
|
387
|
+
this.cropArea.id = 'cropArea';
|
|
388
|
+
this.cropArea.className = 'resize-area hidden';
|
|
387
389
|
this.cropArea.normCoords = { x: 0, y: 0, w: 1, h: 1 };
|
|
388
390
|
const flags = 0x0f;
|
|
389
391
|
this.setCropAreaHandles(flags);
|
|
@@ -398,40 +400,43 @@ class VideoEditor {
|
|
|
398
400
|
this.loadVideo(options);
|
|
399
401
|
}
|
|
400
402
|
if (options.videoArea) {
|
|
401
|
-
options.videoArea.root.classList.add(
|
|
403
|
+
options.videoArea.root.classList.add('lexvideoeditor');
|
|
402
404
|
options.videoArea.attach(this.cropArea);
|
|
403
405
|
videoArea.attach(options.videoArea);
|
|
404
406
|
}
|
|
405
407
|
else {
|
|
406
408
|
videoArea.attach(video);
|
|
407
409
|
videoArea.attach(this.cropArea);
|
|
408
|
-
videoArea.root.classList.add(
|
|
410
|
+
videoArea.root.classList.add('lexvideoeditor');
|
|
409
411
|
}
|
|
410
412
|
this.controlsArea = controlsArea;
|
|
411
413
|
// Create playing timeline area and attach panels
|
|
412
|
-
let [topArea, bottomArea] = controlsArea.split({ type: 'vertical', sizes: [
|
|
414
|
+
let [topArea, bottomArea] = controlsArea.split({ type: 'vertical', sizes: ['50%', null],
|
|
415
|
+
minimizable: false, resize: false });
|
|
413
416
|
bottomArea.setSize([bottomArea.size[0], 40]);
|
|
414
|
-
let [leftArea, controlsRight] = bottomArea.split({ type: 'horizontal', sizes: [
|
|
415
|
-
|
|
417
|
+
let [leftArea, controlsRight] = bottomArea.split({ type: 'horizontal', sizes: ['92%', null],
|
|
418
|
+
minimizable: false, resize: false });
|
|
419
|
+
let [controlsLeft, timeBarArea] = leftArea.split({ type: 'horizontal', sizes: ['10%', null],
|
|
420
|
+
minimizable: false, resize: false });
|
|
416
421
|
topArea.root.classList.add('lexbar');
|
|
417
422
|
bottomArea.root.classList.add('lexbar');
|
|
418
423
|
this.controlsCurrentPanel = new LX.Panel({ className: 'lexcontrolspanel lextime' });
|
|
419
424
|
this.controlsCurrentPanel.refresh = () => {
|
|
420
425
|
this.controlsCurrentPanel.clear();
|
|
421
|
-
this.controlsCurrentPanel.addLabel(this.currentTimeString, { float:
|
|
426
|
+
this.controlsCurrentPanel.addLabel(this.currentTimeString, { float: 'center' });
|
|
422
427
|
};
|
|
423
428
|
topArea.root.classList.add('lexflexarea');
|
|
424
429
|
topArea.attach(this.controlsCurrentPanel);
|
|
425
430
|
this.controlsCurrentPanel.refresh();
|
|
426
431
|
const style = getComputedStyle(bottomArea.root);
|
|
427
|
-
let padding = Number(style.getPropertyValue('padding').replace(
|
|
432
|
+
let padding = Number(style.getPropertyValue('padding').replace('px', ''));
|
|
428
433
|
this.timebar = new TimeBar(timeBarArea, TimeBar.TIMEBAR_TRIM, { offset: padding });
|
|
429
434
|
// Create controls panel (play/pause button and start time)
|
|
430
435
|
this.controlsPanelLeft = new LX.Panel({ className: 'lexcontrolspanel' });
|
|
431
436
|
this.controlsPanelLeft.refresh = () => {
|
|
432
437
|
this.controlsPanelLeft.clear();
|
|
433
438
|
this.controlsPanelLeft.sameLine();
|
|
434
|
-
let playbtn = this.controlsPanelLeft.addButton('Play',
|
|
439
|
+
let playbtn = this.controlsPanelLeft.addButton('Play', '', (v) => {
|
|
435
440
|
this.playing = v;
|
|
436
441
|
if (this.playing) {
|
|
437
442
|
if (this.video.currentTime + 0.000001 >= this.endTime) {
|
|
@@ -442,23 +447,25 @@ class VideoEditor {
|
|
|
442
447
|
else {
|
|
443
448
|
this.video.pause();
|
|
444
449
|
}
|
|
445
|
-
}, { width: '40px', icon: 'Play@solid', swap: 'Pause@solid', hideName: true,
|
|
450
|
+
}, { width: '40px', icon: 'Play@solid', swap: 'Pause@solid', hideName: true,
|
|
451
|
+
className: 'justify-center' });
|
|
446
452
|
playbtn.setState(this.playing, true);
|
|
447
453
|
this.controlsPanelLeft.addButton('', '', (v, e) => {
|
|
448
454
|
const panel = new LX.Panel();
|
|
449
|
-
panel.addRange(
|
|
455
|
+
panel.addRange('Speed', this.speed, (v) => {
|
|
450
456
|
this.speed = v;
|
|
451
457
|
this.video.playbackRate = v;
|
|
452
458
|
if (this.onChangeSpeed) {
|
|
453
459
|
this.onChangeSpeed(v);
|
|
454
460
|
}
|
|
455
461
|
}, { min: 0, max: 2.5, step: 0.01, hideName: true });
|
|
456
|
-
new LX.Popover(e.target, [panel], { align:
|
|
457
|
-
}, { width: '40px', title: 'speed', icon:
|
|
462
|
+
new LX.Popover(e.target, [panel], { align: 'start', side: 'top', sideOffset: 12 });
|
|
463
|
+
}, { width: '40px', title: 'speed', icon: 'Timer@solid', className: 'justify-center' });
|
|
458
464
|
this.controlsPanelLeft.addButton('', 'Loop', (v) => {
|
|
459
465
|
this.loop = v;
|
|
460
|
-
}, { width: '40px', title: 'loop', icon: ('Repeat@solid'), className: `justify-center`, selectable: true,
|
|
461
|
-
|
|
466
|
+
}, { width: '40px', title: 'loop', icon: ('Repeat@solid'), className: `justify-center`, selectable: true,
|
|
467
|
+
selected: this.loop });
|
|
468
|
+
this.controlsPanelLeft.addLabel(this.startTimeString, { width: '100px' });
|
|
462
469
|
this.controlsPanelLeft.endLine();
|
|
463
470
|
let availableWidth = leftArea.root.clientWidth - controlsLeft.root.clientWidth;
|
|
464
471
|
this.timebar.resize([availableWidth, timeBarArea.root.clientHeight]);
|
|
@@ -481,7 +488,8 @@ class VideoEditor {
|
|
|
481
488
|
this.timebar.onChangeEnd = this._setEndTime.bind(this);
|
|
482
489
|
this.resize = () => {
|
|
483
490
|
bottomArea.setSize([this.controlsArea.root.clientWidth, 40]);
|
|
484
|
-
let availableWidth = this.controlsArea.root.clientWidth - controlsLeft.root.clientWidth
|
|
491
|
+
let availableWidth = this.controlsArea.root.clientWidth - controlsLeft.root.clientWidth
|
|
492
|
+
- controlsRight.root.clientWidth;
|
|
485
493
|
this.timebar.resize([availableWidth, timeBarArea.root.clientHeight]);
|
|
486
494
|
this.moveCropArea(this.cropArea.normCoords.x, this.cropArea.normCoords.y, true);
|
|
487
495
|
this.resizeCropArea(this.cropArea.normCoords.w, this.cropArea.normCoords.h, true);
|
|
@@ -492,7 +500,7 @@ class VideoEditor {
|
|
|
492
500
|
area.onresize = this.resize.bind(this);
|
|
493
501
|
window.addEventListener('resize', area.onresize);
|
|
494
502
|
this.onKeyUp = (e) => {
|
|
495
|
-
if (this.controls && e.key ==
|
|
503
|
+
if (this.controls && e.key == ' ') {
|
|
496
504
|
e.preventDefault();
|
|
497
505
|
e.stopPropagation();
|
|
498
506
|
this.playing = !this.playing;
|
|
@@ -508,10 +516,10 @@ class VideoEditor {
|
|
|
508
516
|
this.controlsPanelLeft.refresh();
|
|
509
517
|
}
|
|
510
518
|
};
|
|
511
|
-
window.addEventListener(
|
|
519
|
+
window.addEventListener('keyup', this.onKeyUp);
|
|
512
520
|
const parent = controlsArea.parentElement ? controlsArea.parentElement : controlsArea.root.parentElement;
|
|
513
521
|
// Add canvas event listeneres
|
|
514
|
-
parent.addEventListener(
|
|
522
|
+
parent.addEventListener('mousedown', (e) => {
|
|
515
523
|
// if( this.controls) {
|
|
516
524
|
// this.timebar.onMouseDown(e);
|
|
517
525
|
// }
|
|
@@ -527,8 +535,8 @@ class VideoEditor {
|
|
|
527
535
|
}
|
|
528
536
|
this.isDragging = false;
|
|
529
537
|
this.isResizing = false;
|
|
530
|
-
document.removeEventListener(
|
|
531
|
-
document.removeEventListener(
|
|
538
|
+
document.removeEventListener('mouseup', this._onCropMouseUp); // self destroy. Added during mouseDown on cropArea and handles
|
|
539
|
+
document.removeEventListener('mousemove', this._onCropMouseMove); // self destroy. Added during mouseDown on cropArea and handles
|
|
532
540
|
};
|
|
533
541
|
this._onCropMouseMove = (event) => {
|
|
534
542
|
// if(this.controls) {
|
|
@@ -581,14 +589,14 @@ class VideoEditor {
|
|
|
581
589
|
this.moveCropArea(event.clientX - this.dragOffsetX, event.clientY - this.dragOffsetY, false);
|
|
582
590
|
}
|
|
583
591
|
};
|
|
584
|
-
this.cropArea.addEventListener(
|
|
592
|
+
this.cropArea.addEventListener('mousedown', (e) => {
|
|
585
593
|
if (e.target === this.cropArea) {
|
|
586
594
|
const rect = this.cropArea.getBoundingClientRect();
|
|
587
595
|
this.isDragging = true;
|
|
588
596
|
this.dragOffsetX = e.clientX - rect.left;
|
|
589
597
|
this.dragOffsetY = e.clientY - rect.top;
|
|
590
|
-
document.addEventListener(
|
|
591
|
-
document.addEventListener(
|
|
598
|
+
document.addEventListener('mouseup', this._onCropMouseUp);
|
|
599
|
+
document.addEventListener('mousemove', this._onCropMouseMove);
|
|
592
600
|
}
|
|
593
601
|
});
|
|
594
602
|
this.onChangeStart = null;
|
|
@@ -596,49 +604,45 @@ class VideoEditor {
|
|
|
596
604
|
}
|
|
597
605
|
setCropAreaHandles(flags) {
|
|
598
606
|
// remove existing resizer handles
|
|
599
|
-
const resizers = this.cropArea.getElementsByClassName(
|
|
607
|
+
const resizers = this.cropArea.getElementsByClassName('resize-handle');
|
|
600
608
|
for (let i = resizers.length - 1; i > -1; --i) {
|
|
601
609
|
resizers[i].remove();
|
|
602
610
|
}
|
|
603
611
|
const buildResizer = (className, movement) => {
|
|
604
|
-
const handle = document.createElement(
|
|
605
|
-
handle.className =
|
|
612
|
+
const handle = document.createElement('div');
|
|
613
|
+
handle.className = ' resize-handle ' + className;
|
|
606
614
|
handle.movement = movement;
|
|
607
615
|
if (this.options.handleStyle) {
|
|
608
616
|
Object.assign(handle.style, this.options.handleStyle);
|
|
609
617
|
}
|
|
610
618
|
this.cropArea.append(handle);
|
|
611
|
-
handle.addEventListener(
|
|
619
|
+
handle.addEventListener('mousedown', (e) => {
|
|
612
620
|
e.stopPropagation();
|
|
613
621
|
e.preventDefault();
|
|
614
622
|
this.isResizing = handle;
|
|
615
|
-
document.addEventListener(
|
|
616
|
-
document.addEventListener(
|
|
623
|
+
document.addEventListener('mouseup', this._onCropMouseUp);
|
|
624
|
+
document.addEventListener('mousemove', this._onCropMouseMove);
|
|
617
625
|
});
|
|
618
626
|
};
|
|
619
|
-
if (flags & VideoEditor.CROP_HANDLE_L)
|
|
620
|
-
buildResizer(
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
if (flags & VideoEditor.
|
|
626
|
-
buildResizer(
|
|
627
|
-
}
|
|
628
|
-
if (flags & VideoEditor.CROP_HANDLE_B) {
|
|
629
|
-
buildResizer("b", VideoEditor.CROP_HANDLE_B);
|
|
630
|
-
}
|
|
627
|
+
if (flags & VideoEditor.CROP_HANDLE_L)
|
|
628
|
+
buildResizer('l', VideoEditor.CROP_HANDLE_L);
|
|
629
|
+
if (flags & VideoEditor.CROP_HANDLE_R)
|
|
630
|
+
buildResizer('r', VideoEditor.CROP_HANDLE_R);
|
|
631
|
+
if (flags & VideoEditor.CROP_HANDLE_T)
|
|
632
|
+
buildResizer('t', VideoEditor.CROP_HANDLE_T);
|
|
633
|
+
if (flags & VideoEditor.CROP_HANDLE_B)
|
|
634
|
+
buildResizer('b', VideoEditor.CROP_HANDLE_B);
|
|
631
635
|
if ((flags & VideoEditor.CROP_HANDLE_TL) == VideoEditor.CROP_HANDLE_TL) {
|
|
632
|
-
buildResizer(
|
|
636
|
+
buildResizer('tl', VideoEditor.CROP_HANDLE_TL);
|
|
633
637
|
}
|
|
634
638
|
if ((flags & VideoEditor.CROP_HANDLE_BL) == VideoEditor.CROP_HANDLE_BL) {
|
|
635
|
-
buildResizer(
|
|
639
|
+
buildResizer('bl', VideoEditor.CROP_HANDLE_BL);
|
|
636
640
|
}
|
|
637
641
|
if ((flags & VideoEditor.CROP_HANDLE_TR) == VideoEditor.CROP_HANDLE_TR) {
|
|
638
|
-
buildResizer(
|
|
642
|
+
buildResizer('tr', VideoEditor.CROP_HANDLE_TR);
|
|
639
643
|
}
|
|
640
644
|
if ((flags & VideoEditor.CROP_HANDLE_BR) == VideoEditor.CROP_HANDLE_BR) {
|
|
641
|
-
buildResizer(
|
|
645
|
+
buildResizer('br', VideoEditor.CROP_HANDLE_BR);
|
|
642
646
|
}
|
|
643
647
|
}
|
|
644
648
|
resizeCropArea(sx, sy, isNormalized = true) {
|
|
@@ -655,7 +659,7 @@ class VideoEditor {
|
|
|
655
659
|
const heightPx = rectVideo.height * sy;
|
|
656
660
|
const xPx = rectVideo.width * this.cropArea.normCoords.x + rectVideo.left;
|
|
657
661
|
const yPx = rectVideo.height * this.cropArea.normCoords.y + rectVideo.top;
|
|
658
|
-
if (!this.cropArea.classList.contains(
|
|
662
|
+
if (!this.cropArea.classList.contains('hidden')) {
|
|
659
663
|
const nodes = this.cropArea.parentElement.childNodes;
|
|
660
664
|
for (let i = 0; i < nodes.length; i++) {
|
|
661
665
|
if (nodes[i] != this.cropArea) {
|
|
@@ -665,8 +669,8 @@ class VideoEditor {
|
|
|
665
669
|
}
|
|
666
670
|
}
|
|
667
671
|
}
|
|
668
|
-
this.cropArea.style.width = widthPx +
|
|
669
|
-
this.cropArea.style.height = heightPx +
|
|
672
|
+
this.cropArea.style.width = widthPx + 'px';
|
|
673
|
+
this.cropArea.style.height = heightPx + 'px';
|
|
670
674
|
}
|
|
671
675
|
// screen pixel (event.clientX) or video normalized (0 is top left of video, 1 bot right)
|
|
672
676
|
moveCropArea(x, y, isNormalized = true) {
|
|
@@ -683,7 +687,7 @@ class VideoEditor {
|
|
|
683
687
|
const yPx = rectVideo.height * y + rectVideo.top;
|
|
684
688
|
const widthPx = rectVideo.width * this.cropArea.normCoords.w;
|
|
685
689
|
const heightPx = rectVideo.height * this.cropArea.normCoords.h;
|
|
686
|
-
if (!this.cropArea.classList.contains(
|
|
690
|
+
if (!this.cropArea.classList.contains('hidden')) {
|
|
687
691
|
const nodes = this.cropArea.parentElement.childNodes;
|
|
688
692
|
for (let i = 0; i < nodes.length; i++) {
|
|
689
693
|
if (nodes[i] != this.cropArea) {
|
|
@@ -694,13 +698,13 @@ class VideoEditor {
|
|
|
694
698
|
}
|
|
695
699
|
}
|
|
696
700
|
const rectParent = this.cropArea.parentElement.getBoundingClientRect();
|
|
697
|
-
this.cropArea.style.left = xPx - rectParent.left +
|
|
698
|
-
this.cropArea.style.top = yPx - rectParent.top +
|
|
701
|
+
this.cropArea.style.left = xPx - rectParent.left + 'px';
|
|
702
|
+
this.cropArea.style.top = yPx - rectParent.top + 'px';
|
|
699
703
|
}
|
|
700
704
|
async loadVideo(options = {}) {
|
|
701
705
|
this.videoReady = false;
|
|
702
706
|
while (this.video.duration === Infinity || isNaN(this.video.duration) || !this.timebar) {
|
|
703
|
-
await new Promise(r => setTimeout(r, 1000));
|
|
707
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
704
708
|
this.video.currentTime = 10000000 * Math.random();
|
|
705
709
|
}
|
|
706
710
|
this.video.currentTime = 0.01; // BUG: some videos will not play unless this line is present
|
|
@@ -714,11 +718,11 @@ class VideoEditor {
|
|
|
714
718
|
this.video.currentTime = this.video.duration;
|
|
715
719
|
}
|
|
716
720
|
};
|
|
717
|
-
this.video.addEventListener(
|
|
721
|
+
this.video.addEventListener('canplaythrough', forceLoadChunks, { passive: true });
|
|
718
722
|
this.video.ondurationchange = (v) => {
|
|
719
723
|
if (this.video.duration != this.endTime) {
|
|
720
724
|
this.video.currentTime = this.startTime;
|
|
721
|
-
console.log(
|
|
725
|
+
console.log('duration changed from', this.endTime, ' to ', this.video.duration);
|
|
722
726
|
this.endTime = this.video.duration;
|
|
723
727
|
this.timebar.setDuration(this.endTime);
|
|
724
728
|
this.timebar.setEndTime(this.endTime);
|
|
@@ -734,10 +738,10 @@ class VideoEditor {
|
|
|
734
738
|
this.timebar.setEndTime(this.video.duration);
|
|
735
739
|
this.timebar.setStartTime(this.startTime);
|
|
736
740
|
this.timebar.setCurrentTime(this.startTime);
|
|
737
|
-
//this.timebar.setStartValue( this.timebar.startX);
|
|
738
|
-
//this.timebar.currentX = this._timeToX( this.video.currentTime);
|
|
739
|
-
//this.timebar.setCurrentValue( this.timebar.currentX);
|
|
740
|
-
//this.timebar.update( this.timebar.currentX );
|
|
741
|
+
// this.timebar.setStartValue( this.timebar.startX);
|
|
742
|
+
// this.timebar.currentX = this._timeToX( this.video.currentTime);
|
|
743
|
+
// this.timebar.setCurrentValue( this.timebar.currentX);
|
|
744
|
+
// this.timebar.update( this.timebar.currentX );
|
|
741
745
|
// only have one update on flight
|
|
742
746
|
if (!this.requestId) {
|
|
743
747
|
this._update();
|
|
@@ -746,8 +750,8 @@ class VideoEditor {
|
|
|
746
750
|
if (!this.controls) {
|
|
747
751
|
this.hideControls();
|
|
748
752
|
}
|
|
749
|
-
this.cropArea.style.height = this.video.clientHeight +
|
|
750
|
-
this.cropArea.style.width = this.video.clientWidth +
|
|
753
|
+
this.cropArea.style.height = this.video.clientHeight + 'px';
|
|
754
|
+
this.cropArea.style.width = this.video.clientWidth + 'px';
|
|
751
755
|
this.moveCropArea(0, 0, true);
|
|
752
756
|
this.resizeCropArea(1, 1, true);
|
|
753
757
|
if (this.crop) {
|
|
@@ -756,7 +760,7 @@ class VideoEditor {
|
|
|
756
760
|
else {
|
|
757
761
|
this.hideCropArea();
|
|
758
762
|
}
|
|
759
|
-
window.addEventListener(
|
|
763
|
+
window.addEventListener('keyup', this.onKeyUp);
|
|
760
764
|
if (this.onVideoLoaded) {
|
|
761
765
|
this.onVideoLoaded(this.video);
|
|
762
766
|
}
|
|
@@ -840,7 +844,7 @@ class VideoEditor {
|
|
|
840
844
|
return this.cropArea.getBoundingClientRect();
|
|
841
845
|
}
|
|
842
846
|
showCropArea() {
|
|
843
|
-
this.cropArea.classList.remove(
|
|
847
|
+
this.cropArea.classList.remove('hidden');
|
|
844
848
|
const nodes = this.cropArea.parentElement?.childNodes ?? [];
|
|
845
849
|
const rect = this.cropArea.getBoundingClientRect();
|
|
846
850
|
for (let i = 0; i < nodes.length; i++) {
|
|
@@ -853,13 +857,13 @@ class VideoEditor {
|
|
|
853
857
|
}
|
|
854
858
|
}
|
|
855
859
|
hideCropArea() {
|
|
856
|
-
this.cropArea.classList.add(
|
|
860
|
+
this.cropArea.classList.add('hidden');
|
|
857
861
|
const nodes = this.cropArea.parentElement?.childNodes ?? [];
|
|
858
862
|
for (let i = 0; i < nodes.length; i++) {
|
|
859
863
|
const node = nodes[i];
|
|
860
864
|
if (node == this.cropArea)
|
|
861
865
|
continue;
|
|
862
|
-
node.style.webkitMask =
|
|
866
|
+
node.style.webkitMask = '';
|
|
863
867
|
node.style.webkitMaskRepeat = 'no-repeat';
|
|
864
868
|
}
|
|
865
869
|
}
|
|
@@ -882,10 +886,10 @@ class VideoEditor {
|
|
|
882
886
|
this.video.pause();
|
|
883
887
|
this.playing = false;
|
|
884
888
|
this.controlsPanelLeft.refresh();
|
|
885
|
-
this.video.src =
|
|
886
|
-
window.removeEventListener(
|
|
887
|
-
document.removeEventListener(
|
|
888
|
-
document.removeEventListener(
|
|
889
|
+
this.video.src = '';
|
|
890
|
+
window.removeEventListener('keyup', this.onKeyUp);
|
|
891
|
+
document.removeEventListener('mouseup', this._onCropMouseUp);
|
|
892
|
+
document.removeEventListener('mousemove', this._onCropMouseMove);
|
|
889
893
|
}
|
|
890
894
|
}
|
|
891
895
|
LX.VideoEditor = VideoEditor;
|