@vidispine/vdt-videojs 21.3.0 → 22.1.0-pre.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.
Files changed (55) hide show
  1. package/README.md +4 -4
  2. package/deprecated-app/README.md +21 -0
  3. package/{demo.html → deprecated-app/index.html} +1 -1
  4. package/{demo.js → deprecated-app/index.js} +69 -41
  5. package/{samples → deprecated-app/samples}/birds-es.vvt +0 -0
  6. package/{samples → deprecated-app/samples}/birds.vvt +0 -0
  7. package/{tests.js → deprecated-app/tests.js} +87 -54
  8. package/{lib/style.css → dist/index.css} +755 -55
  9. package/dist/index.es.js +2099 -0
  10. package/dist/index.js +2112 -0
  11. package/dist/index.umd.js +2115 -0
  12. package/package.json +29 -85
  13. package/rollup.config.js +54 -0
  14. package/src/constants.js +1 -1
  15. package/src/externalControls.js +14 -18
  16. package/src/helpOverlay.js +12 -16
  17. package/src/helpers.js +3 -3
  18. package/src/index.js +3 -9
  19. package/src/index.stories.mdx +59 -0
  20. package/src/menu.api.stories.mdx +59 -0
  21. package/src/menu.js +23 -19
  22. package/src/{menu.example.md → menu.usage.stories.mdx} +31 -21
  23. package/src/osd.js +24 -18
  24. package/src/player.api.stories.mdx +120 -0
  25. package/src/player.js +157 -108
  26. package/src/player.scss +2 -0
  27. package/src/{player.example.md → player.usage.stories.mdx} +18 -8
  28. package/src/seekBar.js +85 -48
  29. package/src/timeCodeDisplay.js +39 -31
  30. package/src/videoTime.js +4 -4
  31. package/build.js +0 -233
  32. package/lib/index.cjs.js +0 -3240
  33. package/lib/index.esm.js +0 -3227
  34. package/lib/index.umd.js +0 -3243
  35. package/lib/package.json +0 -13
  36. package/lib/src/constants.js +0 -51
  37. package/lib/src/externalControls.js +0 -307
  38. package/lib/src/helpOverlay.js +0 -106
  39. package/lib/src/helpers.js +0 -34
  40. package/lib/src/index.js +0 -13
  41. package/lib/src/menu.js +0 -365
  42. package/lib/src/osd.js +0 -91
  43. package/lib/src/player.js +0 -943
  44. package/lib/src/seekBar.js +0 -833
  45. package/lib/src/timeCodeDisplay.js +0 -253
  46. package/lib/src/videoTime.js +0 -66
  47. package/log.js +0 -24
  48. package/src/_index.stories.js +0 -24
  49. package/src/externalControls.stories.js +0 -6
  50. package/src/helpOverlay.stories.js +0 -6
  51. package/src/menu.classMethods.md +0 -47
  52. package/src/player.classMethods.md +0 -108
  53. package/src/player.stories.js +0 -14
  54. package/src/seekBar.stories.js +0 -8
  55. package/tmp/player.css +0 -1
@@ -1,833 +0,0 @@
1
-
2
- import mousetrap from 'mousetrap';
3
- import { truncate, sanitize, reactiveSetters } from './helpers';
4
- import { classNames, colors } from './constants';
5
-
6
- const constants = Object.freeze({
7
- className: 'vdt-seekbar',
8
- defaults: {
9
- bgColor: '#fafafa',
10
- fillColor: '#f00',
11
- regionColor: '#f6e58d',
12
- markerWidth: 16,
13
- regionAccentColor: '#00a8ff',
14
- transitionTime: 300,
15
- },
16
- markerTypes: {
17
- in: 'in',
18
- out: 'out',
19
- },
20
- });
21
-
22
- const CSS = (bgColor, fillColor) => `
23
- .${constants.className}{
24
- user-select: none;
25
- background: ${colors.light};
26
- height: 6px;
27
- width: 100%;
28
- position: relative;
29
- cursor: pointer;
30
- z-index: 5;
31
- }
32
-
33
- .${classNames.onDark}.${constants.className}{
34
- background: ${colors.gray};
35
- }
36
-
37
- .fill, .load-indicator{
38
- height: 100%;
39
- display: inline-block;
40
- position: absolute;
41
- left: 0px;
42
- top: 0px;
43
- background: ${fillColor};
44
- transition: width ${constants.defaults.transitionTime}ms linear;
45
- z-index: 2;
46
- }
47
-
48
- .load-indicator{
49
- background: #e1e1e1;
50
- z-index: 1;
51
- opacity: .2;
52
- transition: none;
53
- }
54
-
55
- .${classNames.onDark}.${constants.className} .load-indicator{
56
- background: white;
57
- }
58
-
59
- .${constants.className}.dragging .fill{
60
- transition: none;
61
- }
62
-
63
-
64
- .marker, .region{
65
- position: absolute;
66
- top: 0px;
67
- height: 100%;
68
- background: cyan;
69
- width: 1px;
70
- display: inline-block;
71
- z-index: 4;
72
- }
73
-
74
- .marker{
75
- transition: opacity ${constants.defaults.transitionTime}ms linear;
76
- }
77
-
78
- .marker{ display: none; }
79
- .marker.active{ display: initial; }
80
-
81
- .marker .handle{
82
- position: absolute;
83
- bottom: 10px; right: 0px;
84
- width: ${constants.defaults.markerWidth}px;
85
- height: 28px;
86
- background: #999;
87
- border-radius: 3px;
88
- cursor: col-resize;
89
- z-index: 3;
90
- box-sizing: border-box;
91
- }
92
-
93
- .marker.regional .handle{
94
- background: ${constants.defaults.regionAccentColor};
95
- box-shadow: -2px 1px 1px rgba(0,0,0,.1);
96
- }
97
-
98
- .marker.regional.in .handle{
99
- box-shadow: 2px 1px 1px rgba(0,0,0,.1);
100
- }
101
-
102
- .marker.in .handle{
103
- border-bottom-left-radius: 40px;
104
- }
105
-
106
- .marker.out .handle{
107
- left: 1px;
108
- right: initial;
109
- border-bottom-right-radius: 20px;
110
- }
111
-
112
- .handle:active{
113
- background: ${constants.defaults.regionColor};
114
- }
115
-
116
- .region{
117
- position: absolute;
118
- width: auto;
119
- background: ${constants.defaults.regionColor};
120
- opacity: .7;
121
- }
122
-
123
- .region.nav{
124
- background: transparent;
125
- opacity: 1;
126
- border-left: 1px solid cyan;
127
- }
128
-
129
- .region.nav .bubble,
130
- .region.nav:after{
131
- content: " ";
132
- height: 16px;
133
- bottom: 10px;
134
- width: 16px;
135
- border-radius: 16px;
136
- background: ${constants.defaults.regionAccentColor};
137
- position: absolute;
138
- margin-left: -8px;
139
- transition: transform 200ms ease-out;
140
- transform: translate3d(0px, 0px, 0px);
141
- transform-origin: bottom center;
142
- }
143
-
144
- .region.nav .popout{
145
- width: 160px;
146
- z-index: 4;
147
- background: rgba(28, 28, 28, .7);
148
- color: white;
149
- font-size: 14px;
150
- min-height: 100px;
151
- bottom: 16px;
152
- left: -80px;
153
- position: absolute;
154
- border-radius: 8px;
155
- -webkit-backdrop-filter: blur(10px);
156
- font-family: Arial, Helvetica, sans-serif;
157
- overflow: hidden;
158
- opacity: 0;
159
- visibility: hidden;
160
- }
161
-
162
- .region.nav.right-aligned .popout{
163
- right: 0px;
164
- left: initial;
165
- }
166
-
167
- .region.nav.left-aligned .popout{
168
- left: -32px;
169
- }
170
-
171
- .region.nav .popout .title{
172
- padding: 4px 14px;
173
- text-align: center;
174
- color: black;
175
- background: white;
176
- }
177
-
178
- .region.nav .popout .annotation{
179
- padding: 8px 12px;
180
- font-weight: light;
181
- color: rgba(255,255,255,.9);
182
- }
183
-
184
- .region.nav:after{
185
- width: 1px;
186
- left: 8px;
187
- height: 10px;
188
- bottom: 0px;
189
- background: #00a8ff;
190
- }
191
-
192
- .region.nav:hover{
193
- background: rgba(28, 28, 28, .5);
194
- }
195
-
196
- .region.nav.has-popout:hover .bubble{
197
- background: rgba(28, 28, 28, .8);
198
- opacity: 1;
199
- z-index: 3;
200
- }
201
-
202
- .region.nav:hover:after,
203
- .region.nav:hover:before{
204
- background: rgba(28, 28, 28, .8);
205
- }
206
-
207
- .region.nav:hover .popout{
208
- opacity: 1;
209
- visibility: visible;
210
- }
211
-
212
- .${constants.className}.dragging .bubble{
213
- transform: scale3d(.75,.75,.75);
214
- }
215
-
216
- .${constants.className}.hide-markers .marker{
217
- opacity: 0;
218
- }
219
-
220
- `;
221
-
222
- export class Region {
223
- constructor(props) {
224
- const regionDefaultProps = {
225
- in: null,
226
- out: null,
227
- title: '',
228
- annotation: '',
229
- el: null, // can store a
230
- };
231
-
232
- Object.assign(this, regionDefaultProps, props); // apply props
233
- }
234
- }
235
-
236
- export default class SeekBar {
237
- constructor(props) {
238
- this.props = props;
239
- reactiveSetters.apply(this); // ability to handle new props via setters
240
-
241
- this.container = document.createElement('div');
242
- this.container.className = `${constants.className}-wrapper`;
243
-
244
- this.state = {
245
- in: null,
246
- out: null,
247
- markersEnabled: (this.props.markersEnabled === undefined) ? true : this.props.markersEnabled,
248
- regions: [],
249
- dragging: false,
250
- };
251
-
252
- this.markers = {};
253
-
254
- if (this.props.target) {
255
- this.shadow = this.container.attachShadow({ mode: 'open' });
256
- this.props.target.appendChild(this.container);
257
-
258
- this.style = document.createElement('style');
259
- this.style.type = 'text/css';
260
-
261
-
262
- const bgColor = (this.props.bgColor) ? this.props.bgColor : constants.defaults.bgColor;
263
- const fillColor = (this.props.fillColor) ? this.props.fillColor : constants.defaults.fillColor;
264
-
265
- this.style.innerHTML = CSS(sanitize(bgColor), sanitize(fillColor));
266
- this.shadow.appendChild(this.style);
267
- }
268
-
269
- this.bindEvents();
270
- this.draw();
271
- this.bindHotkeys();
272
-
273
- const { player } = this.props;
274
- if (player) {
275
- player.videojs.on('loadedmetadata', () => {
276
- this.handleNewProps(this.props);
277
- });
278
- }
279
- }
280
-
281
- bindEvents() {
282
- if (this.props.player) {
283
- const { player } = this.props;
284
- player.videojs.on('timeupdate', () => {
285
- const progressFraction = player.videojs.currentTime() / player.videojs.duration();
286
- this.fill.style.width = `${100 * progressFraction}%`;
287
- });
288
-
289
- player.videojs.on('progress', () => {
290
- this.percentLoaded = player.percentLoaded;
291
- });
292
- }
293
- }
294
-
295
- bindHotkeys() {
296
- this.bindings = [];
297
-
298
-
299
- if (this.props.player) {
300
- const { player } = this.props;
301
- this.bindings = [
302
- {
303
- key: ['i'],
304
- method: () => {
305
- if (this.markersEnabled) this.in = player.videojs.currentTime();
306
- },
307
- },
308
- {
309
- key: ['o'],
310
- method: () => {
311
- if (this.markersEnabled) this.out = player.videojs.currentTime();
312
- },
313
- },
314
- {
315
- key: ['shift+i'],
316
- method: () => {
317
- if (this.markersEnabled) this.navigateToIn();
318
- },
319
- },
320
- {
321
- key: ['shift+o'],
322
- method: () => {
323
- if (this.markersEnabled) this.navigateToOut();
324
- },
325
- },
326
- ];
327
- }
328
-
329
- if (this.props.player) {
330
- const { player } = this.props;
331
- mousetrap.bind('i', () => {
332
- if (this.markersEnabled) this.in = player.videojs.currentTime();
333
- });
334
-
335
- mousetrap.bind('o', () => {
336
- if (this.markersEnabled) this.out = player.videojs.currentTime();
337
- });
338
-
339
- mousetrap.bind('shift+i', () => {
340
- if (this.markersEnabled) this.navigateToIn();
341
- });
342
-
343
- mousetrap.bind('shift+o', () => {
344
- if (this.markersEnabled) this.navigateToOut();
345
- });
346
- }
347
-
348
-
349
- this.bindings.forEach((binding) => {
350
- mousetrap.bind(binding.key, (e) => {
351
- binding.method(e);
352
- });
353
- });
354
- }
355
-
356
- unbindHotKeys() {
357
- this.bindings && this.bindings.forEach((binding) => {
358
- mousetrap.unbind(binding.key);
359
- });
360
- }
361
-
362
- handleSeek(event) {
363
-
364
- if (this.props.player) {
365
- const { player } = this.props;
366
- if (this.state.regions) {
367
- let clickedOnRegion = false;
368
- let preventSeek = false;
369
- this.state.regions.forEach((region) => {
370
- if (region.el.contains(event.target)) {
371
-
372
-
373
-
374
-
375
- if (this.props.onRegionClick) {
376
- preventSeek = (this.props.onRegionClick(region));
377
- if (!preventSeek) {
378
- player.seekTo(region.in);
379
- }
380
- } else {
381
- player.seekTo(region.in);
382
- }
383
-
384
- clickedOnRegion = true;
385
- }
386
- });
387
-
388
-
389
- if (clickedOnRegion) return;
390
- }
391
-
392
- const seekFractionX = (event.clientX - this.bar.getBoundingClientRect().left) / this.bar.offsetWidth;
393
-
394
-
395
- const timeToSeek = seekFractionX * player.videojs.duration();
396
-
397
- player.seekTo(timeToSeek);
398
- }
399
- }
400
-
401
- handleSeekDrag(mouseDownEvent) {
402
- const barOffset = this.bar.getBoundingClientRect().left;
403
- const barWidth = this.bar.getBoundingClientRect().width;
404
- const duration = this.props.player.videojs.duration();
405
- let left;
406
-
407
- const drag = (e) => {
408
- left = e.clientX - barOffset;
409
- const pxDragged = Math.abs(mouseDownEvent.clientX - e.clientX);
410
-
411
- if (left >= 0 && left < barWidth && pxDragged > 1) {
412
- this.dragging = true;
413
- const fractionFromStart = parseFloat(left) / barWidth;
414
- const seconds = fractionFromStart * duration;
415
- this.props.player.videojs.currentTime(seconds);
416
- }
417
-
418
- e.preventDefault();
419
- };
420
-
421
- const stopDrag = (e) => {
422
- this.dragging = false;
423
-
424
-
425
- document.removeEventListener('mousemove', drag, false);
426
- document.removeEventListener('mouseup', stopDrag, false);
427
-
428
- const fractionFromStart = parseFloat(left) / barWidth;
429
- const seconds = fractionFromStart * duration;
430
- this.props.player.videojs.currentTime(seconds);
431
-
432
- e.stopPropagation();
433
- };
434
-
435
-
436
- document.addEventListener('mousemove', drag, false);
437
- document.addEventListener('mouseup', stopDrag, false);
438
- }
439
-
440
- draw() {
441
- this.bar = document.createElement('div');
442
- this.bar.className = constants.className;
443
- this.bar.onclick = (e) => {
444
- if (!e.target.classList.contains('marker') && !e.target.classList.contains('handle')) {
445
- this.handleSeek(e);
446
- }
447
- };
448
-
449
-
450
-
451
- this.bar.addEventListener('mousedown', (e) => {
452
- e.preventDefault();
453
-
454
- if (!this.dragging) {
455
- this.handleSeekDrag(e);
456
- }
457
- }, false);
458
-
459
- this.fill = document.createElement('div');
460
- this.fill.className = 'fill';
461
-
462
- this.loadIndicator = document.createElement('div');
463
- this.loadIndicator.className = 'load-indicator';
464
-
465
- this.region = document.createElement('div');
466
- this.region.className = 'region';
467
-
468
- this.bar.appendChild(this.fill);
469
- this.bar.appendChild(this.loadIndicator);
470
- this.bar.appendChild(this.region);
471
- this.shadow.appendChild(this.bar);
472
-
473
- this.drawMarkers();
474
- }
475
-
476
- drawMarkers() {
477
- if (this.markersEnabled) {
478
- const markerIn = this.markers[constants.markerTypes.in] = document.createElement('div');
479
- const markerOut = this.markers[constants.markerTypes.out] = document.createElement('div');
480
- markerIn.className = `marker ${constants.markerTypes.in}`;
481
- markerOut.className = `marker ${constants.markerTypes.out}`;
482
-
483
- const handleIn = document.createElement('div');
484
- const handleOut = document.createElement('div');
485
- handleIn.className = handleOut.className = 'handle';
486
-
487
- handleIn.addEventListener('mousedown', (e) => {
488
- e.preventDefault();
489
- e.stopPropagation();
490
-
491
- this.handleMarkerDrag(markerIn, constants.markerTypes.in, e);
492
- }, false);
493
-
494
- handleOut.addEventListener('mousedown', (e) => {
495
- e.preventDefault();
496
- e.stopPropagation();
497
-
498
- this.handleMarkerDrag(markerOut, constants.markerTypes.out, e);
499
- }, false);
500
-
501
- markerIn.appendChild(handleIn);
502
- markerOut.appendChild(handleOut);
503
-
504
- this.bar.appendChild(markerIn);
505
- this.bar.appendChild(markerOut);
506
- }
507
- }
508
-
509
- updateMarkers(marker) {
510
- this.markers[marker.type].style.left = `${marker.value * 100}%`;
511
- this.markers[marker.type].classList.add('active');
512
-
513
-
514
- if (this.state.regions) {
515
-
516
- const matchingRegions = [];
517
- const isRegional = (matchingRegions.length > 0);
518
- if (isRegional) {
519
- this.markers[marker.type].classList.add('regional');
520
- } else {
521
- this.markers[marker.type].classList.remove('regional');
522
- }
523
- }
524
-
525
- this.drawInAndOutRegion();
526
- }
527
-
528
- drawInAndOutRegion() {
529
- if (this.state.in !== null && this.state.out !== null) {
530
- this.region.style.left = this.markers[constants.markerTypes.in].style.left;
531
- this.region.style.right = `${100 - parseFloat(this.markers[constants.markerTypes.out].style.left.replace('%', ''))}%`;
532
- } else {
533
-
534
- }
535
- }
536
-
537
- handleMarkerDrag(markerNode, type, mouseDownEvent) {
538
- const barOffset = this.bar.getBoundingClientRect().left;
539
- const barWidth = this.bar.getBoundingClientRect().width;
540
- const duration = this.props.player.videojs.duration();
541
- let dragHappened = false;
542
-
543
- const drag = (e) => {
544
- const pxDragged = Math.abs(mouseDownEvent.clientX - e.clientX);
545
- const markerOffset = (type === constants.markerTypes.in) ? (constants.defaults.markerWidth / 2) : -(constants.defaults.markerWidth / 2);
546
- const left = e.clientX - barOffset + markerOffset;
547
-
548
- if (left >= 0 && left < barWidth && pxDragged > 1) {
549
- dragHappened = this.dragging = true;
550
- markerNode.style.left = `${left}px`;
551
- markerNode.classList.add('active');
552
-
553
- const fractionFromStart = parseFloat(markerNode.getBoundingClientRect().left - barOffset) / barWidth;
554
- const seconds = fractionFromStart * duration;
555
- this.props.player.videojs.currentTime(seconds);
556
- }
557
-
558
- e.preventDefault();
559
- };
560
-
561
- const stopDrag = (e) => {
562
- this.dragging = false;
563
-
564
-
565
- document.removeEventListener('mousemove', drag, false);
566
- document.removeEventListener('mouseup', stopDrag, false);
567
-
568
- const fractionFromStart = parseFloat(markerNode.getBoundingClientRect().left - barOffset) / barWidth;
569
- const seconds = fractionFromStart * duration;
570
- this[type] = seconds;
571
- this.props.player.videojs.currentTime(seconds);
572
-
573
- if (!dragHappened) {
574
- if (type === constants.markerTypes.in) {
575
- this.navigateToIn();
576
- } else {
577
- this.navigateToOut();
578
- }
579
- }
580
-
581
- this.props.onDragFinish && this.props.onDragFinish({ type, seconds });
582
- e.stopPropagation();
583
- };
584
-
585
-
586
- document.addEventListener('mousemove', drag, false);
587
- document.addEventListener('mouseup', stopDrag, false);
588
- }
589
-
590
- cleanupMarkers() {
591
- let removedMarker = false;
592
- if (this.state.in === null) {
593
- this.markers[constants.markerTypes.in].classList.remove('active');
594
- removedMarker = true;
595
- }
596
-
597
- if (this.state.out === null) {
598
- this.markers[constants.markerTypes.out].classList.remove('active');
599
- removedMarker = true;
600
- }
601
-
602
- if (removedMarker) {
603
- this.region.style.left = 'initial';
604
- this.region.style.right = 'initial';
605
- }
606
- }
607
-
608
- clearMarkers() {
609
- this.in = null;
610
- this.out = null;
611
- }
612
-
613
-
614
- setInFromCurrent() {
615
- this.in = this.props.player.videojs.currentTime();
616
- }
617
-
618
- setOutFromCurrent() {
619
- this.out = this.props.player.videojs.currentTime();
620
- }
621
-
622
- navigateToIn() {
623
- const { player } = this.props;
624
- player.seekTo(this.in);
625
- }
626
-
627
- navigateToOut() {
628
- const { player } = this.props;
629
- player.seekTo(this.out);
630
- }
631
-
632
-
633
- set in(val) {
634
- if (!this.state.markersEnabled) return;
635
-
636
- this.state.in = val;
637
-
638
- if (val !== null && val !== undefined) {
639
- const { player } = this.props;
640
- this.updateMarkers({
641
- type: constants.markerTypes.in,
642
- value: val / player.videojs.duration(),
643
- });
644
-
645
-
646
- if (this.state.out !== null && val > this.state.out) {
647
- this.out = null;
648
- }
649
-
650
- this.props.onIn && this.props.onIn(this.state.in);
651
- } else {
652
- this.cleanupMarkers();
653
- }
654
- }
655
-
656
- get in() {
657
- return this.state.in;
658
- }
659
-
660
- set out(val) {
661
- if (!this.state.markersEnabled) return;
662
-
663
- this.state.out = val;
664
-
665
- if (val !== null && val !== undefined) {
666
- const { player } = this.props;
667
- this.updateMarkers({
668
- type: constants.markerTypes.out,
669
- value: val / player.videojs.duration(),
670
- });
671
-
672
-
673
- if (this.state.in != null && val < this.state.in) {
674
- this.in = null;
675
- }
676
-
677
- this.props.onOut && this.props.onOut(this.state.out);
678
- } else {
679
- this.cleanupMarkers();
680
- }
681
- }
682
-
683
- get out() {
684
- return this.state.out;
685
- }
686
-
687
- get markersEnabled() {
688
- return this.state.markersEnabled;
689
- }
690
-
691
- set markersEnabled(bool) {
692
- if (typeof bool === 'boolean') {
693
- if (!bool) {
694
- this.clearMarkers();
695
- this.state.markersEnabled = false;
696
- } else {
697
- !this.markersEnabled && this.drawMarkers();
698
- this.state.markersEnabled = true;
699
- }
700
- }
701
- }
702
-
703
- set regions(regionArray) {
704
- if (this.state.regions.length < 1) {
705
- regionArray && regionArray.forEach((region) => {
706
- this.addRegion(region);
707
- });
708
- } else {
709
- this.state.regions.forEach((region, index) => {
710
- this.removeRegion(index);
711
- });
712
-
713
- this.state.regions = [];
714
- this.regions = regionArray;
715
- }
716
- }
717
-
718
- get regions() {
719
- return this.state.regions;
720
- }
721
-
722
- set dragging(bool) {
723
-
724
- if (bool && !this.state.dragging) {
725
- this.state.dragging = true;
726
- this.bar.classList.add('dragging');
727
- } else if (!bool && this.state.dragging) {
728
- this.state.dragging = false;
729
- this.bar.classList.remove('dragging');
730
- }
731
- }
732
-
733
- get dragging() {
734
- return this.state.dragging;
735
- }
736
-
737
- addRegion(regionObj) {
738
- if (regionObj.constructor.name === Region.name) {
739
- this.state.regions.push(regionObj);
740
- this.drawRegion(regionObj);
741
- } else {
742
- this.addRegion(new Region(regionObj));
743
- }
744
- }
745
-
746
- removeRegion(param) {
747
- if (typeof param === typeof Region) {
748
-
749
- } else {
750
- this.state.regions[param].el.remove();
751
- this.state.regions[param] = null;
752
- delete this.state.regions[param];
753
- }
754
- }
755
-
756
- drawRegion(region) {
757
- const duration = this.props.player.videojs.duration();
758
- const inPoint = region.in;
759
-
760
- const leftPercentage = (inPoint / duration) * 100;
761
- const rightPercentage = ((duration - region.out) / duration) * 100;
762
-
763
- const regionEl = document.createElement('div');
764
- regionEl.className = 'region nav ';
765
- regionEl.innerHTML = '<div class="bubble"></div>';
766
-
767
- if (region.title && region.annotation) {
768
- let alignmentClassName = '';
769
- if (leftPercentage > 70) alignmentClassName = 'right-aligned';
770
- if (leftPercentage < 30) alignmentClassName = 'left-aligned';
771
- regionEl.className += ` has-popout ${alignmentClassName}`;
772
-
773
- const popout = document.createElement('div');
774
-
775
- popout.className = 'popout';
776
- popout.innerHTML = `
777
- <div class="title">
778
- ${sanitize(region.title)}
779
- </div>
780
- <div class="annotation">
781
- ${truncate(sanitize(region.annotation), 72)}
782
- </div>
783
- `;
784
-
785
- regionEl.appendChild(popout);
786
- }
787
-
788
- regionEl.style.left = `${leftPercentage}%`;
789
- regionEl.style.right = `${rightPercentage}%`;
790
-
791
- region.el = regionEl;
792
-
793
- this.bar.appendChild(regionEl);
794
- }
795
-
796
- set onDark(bool) {
797
- if (bool) {
798
- this.bar.classList.add(classNames.onDark);
799
- } else {
800
- this.bar.classList.remove(classNames.onDark);
801
- }
802
- }
803
-
804
- get onDark() {
805
- return this.container.classList.contains(classNames.onDark);
806
- }
807
-
808
- set percentLoaded(val) {
809
- this.loadIndicator.style.width = `${val}%`;
810
- }
811
-
812
- destroy() {
813
- this.unbindHotKeys();
814
- }
815
-
816
- toggleMarkers() {
817
- if (this.bar.classList.contains('hide-markers')) {
818
- this.showMarkers();
819
- } else {
820
- this.hideMarkers();
821
- }
822
- }
823
-
824
- hideMarkers() {
825
- this.bar.classList.add('hide-markers');
826
- }
827
-
828
- showMarkers() {
829
- this.bar.classList.remove('hide-markers');
830
- }
831
- }
832
-
833
- SeekBar.Region = Region;