unified-video-framework 1.4.110 → 1.4.112
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/package.json +1 -1
- package/packages/web/dist/WebPlayer.d.ts +0 -3
- package/packages/web/dist/WebPlayer.d.ts.map +1 -1
- package/packages/web/dist/WebPlayer.js +2 -295
- package/packages/web/dist/WebPlayer.js.map +1 -1
- package/packages/web/package.json +1 -1
- package/packages/web/src/WebPlayer.ts +2 -325
|
@@ -2099,150 +2099,7 @@ export class WebPlayer extends BasePlayer {
|
|
|
2099
2099
|
box-shadow: 0 0 20px rgba(255, 87, 34, 0.5);
|
|
2100
2100
|
}
|
|
2101
2101
|
|
|
2102
|
-
.uvf-progress-handle {
|
|
2103
|
-
position: absolute;
|
|
2104
|
-
width: 12px;
|
|
2105
|
-
height: 12px;
|
|
2106
|
-
background: radial-gradient(circle,
|
|
2107
|
-
rgba(255, 255, 255, 0.95) 0%,
|
|
2108
|
-
rgba(255, 255, 255, 0.9) 70%,
|
|
2109
|
-
rgba(255, 255, 255, 0.85) 100%
|
|
2110
|
-
);
|
|
2111
|
-
border: 2px solid rgba(255, 87, 34, 0.8);
|
|
2112
|
-
border-radius: 50%;
|
|
2113
|
-
top: 50%;
|
|
2114
|
-
left: 0%;
|
|
2115
|
-
transform: translate(-50%, -50%) scale(0);
|
|
2116
|
-
opacity: 0;
|
|
2117
|
-
transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
2118
|
-
box-shadow:
|
|
2119
|
-
0 0 0 0 rgba(255, 87, 34, 0.4),
|
|
2120
|
-
0 4px 12px rgba(0, 0, 0, 0.25),
|
|
2121
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.4);
|
|
2122
|
-
cursor: grab;
|
|
2123
|
-
z-index: 3;
|
|
2124
|
-
pointer-events: all;
|
|
2125
|
-
backdrop-filter: blur(8px);
|
|
2126
|
-
}
|
|
2127
2102
|
|
|
2128
|
-
.uvf-progress-bar-wrapper:hover .uvf-progress-handle {
|
|
2129
|
-
opacity: 1;
|
|
2130
|
-
transform: translate(-50%, -50%) scale(1);
|
|
2131
|
-
box-shadow:
|
|
2132
|
-
0 0 0 4px rgba(255, 87, 34, 0.2),
|
|
2133
|
-
0 6px 20px rgba(0, 0, 0, 0.3),
|
|
2134
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.6);
|
|
2135
|
-
}
|
|
2136
|
-
|
|
2137
|
-
.uvf-progress-handle:hover {
|
|
2138
|
-
transform: translate(-50%, -50%) scale(1.25);
|
|
2139
|
-
background: radial-gradient(circle,
|
|
2140
|
-
rgba(255, 255, 255, 1) 0%,
|
|
2141
|
-
rgba(255, 255, 255, 0.95) 70%,
|
|
2142
|
-
rgba(255, 255, 255, 0.9) 100%
|
|
2143
|
-
);
|
|
2144
|
-
border-color: rgba(255, 87, 34, 1);
|
|
2145
|
-
box-shadow:
|
|
2146
|
-
0 0 0 6px rgba(255, 87, 34, 0.3),
|
|
2147
|
-
0 8px 25px rgba(255, 87, 34, 0.4),
|
|
2148
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
|
2149
|
-
}
|
|
2150
|
-
|
|
2151
|
-
.uvf-progress-handle:active,
|
|
2152
|
-
.uvf-progress-handle.dragging {
|
|
2153
|
-
cursor: grabbing;
|
|
2154
|
-
transform: translate(-50%, -50%) scale(1.4);
|
|
2155
|
-
background: radial-gradient(circle,
|
|
2156
|
-
rgba(255, 255, 255, 1) 0%,
|
|
2157
|
-
rgba(255, 255, 255, 0.98) 50%,
|
|
2158
|
-
rgba(255, 255, 255, 0.95) 100%
|
|
2159
|
-
);
|
|
2160
|
-
border-color: #ff4500;
|
|
2161
|
-
box-shadow:
|
|
2162
|
-
0 0 0 8px rgba(255, 87, 34, 0.4),
|
|
2163
|
-
0 12px 35px rgba(255, 69, 0, 0.5),
|
|
2164
|
-
inset 0 2px 0 rgba(255, 255, 255, 0.9);
|
|
2165
|
-
transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1);
|
|
2166
|
-
}
|
|
2167
|
-
|
|
2168
|
-
.uvf-time-tooltip {
|
|
2169
|
-
position: absolute;
|
|
2170
|
-
bottom: 32px;
|
|
2171
|
-
left: 0;
|
|
2172
|
-
transform: translateX(-50%) translateY(8px) scale(0.9);
|
|
2173
|
-
background: linear-gradient(135deg,
|
|
2174
|
-
rgba(0, 0, 0, 0.95) 0%,
|
|
2175
|
-
rgba(20, 20, 20, 0.92) 50%,
|
|
2176
|
-
rgba(0, 0, 0, 0.98) 100%
|
|
2177
|
-
);
|
|
2178
|
-
color: #ffffff;
|
|
2179
|
-
padding: 10px 16px;
|
|
2180
|
-
border-radius: 12px;
|
|
2181
|
-
font-size: 13px;
|
|
2182
|
-
font-weight: 600;
|
|
2183
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
2184
|
-
letter-spacing: 0.5px;
|
|
2185
|
-
white-space: nowrap;
|
|
2186
|
-
opacity: 0;
|
|
2187
|
-
transition: all 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
2188
|
-
pointer-events: none;
|
|
2189
|
-
z-index: 4;
|
|
2190
|
-
box-shadow:
|
|
2191
|
-
0 0 0 1px rgba(255, 255, 255, 0.05),
|
|
2192
|
-
0 8px 32px rgba(0, 0, 0, 0.6),
|
|
2193
|
-
0 2px 8px rgba(0, 0, 0, 0.3),
|
|
2194
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
2195
|
-
backdrop-filter: blur(20px) saturate(1.5);
|
|
2196
|
-
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
2197
|
-
min-width: 52px;
|
|
2198
|
-
text-align: center;
|
|
2199
|
-
}
|
|
2200
|
-
|
|
2201
|
-
/* Glass morphism tooltip arrow with multiple layers */
|
|
2202
|
-
.uvf-time-tooltip::after {
|
|
2203
|
-
content: '';
|
|
2204
|
-
position: absolute;
|
|
2205
|
-
bottom: -10px;
|
|
2206
|
-
left: 50%;
|
|
2207
|
-
transform: translateX(-50%);
|
|
2208
|
-
width: 0;
|
|
2209
|
-
height: 0;
|
|
2210
|
-
border-left: 10px solid transparent;
|
|
2211
|
-
border-right: 10px solid transparent;
|
|
2212
|
-
border-top: 10px solid rgba(0, 0, 0, 0.95);
|
|
2213
|
-
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
|
|
2214
|
-
}
|
|
2215
|
-
|
|
2216
|
-
.uvf-time-tooltip::before {
|
|
2217
|
-
content: '';
|
|
2218
|
-
position: absolute;
|
|
2219
|
-
bottom: -11px;
|
|
2220
|
-
left: 50%;
|
|
2221
|
-
transform: translateX(-50%);
|
|
2222
|
-
width: 0;
|
|
2223
|
-
height: 0;
|
|
2224
|
-
border-left: 11px solid transparent;
|
|
2225
|
-
border-right: 11px solid transparent;
|
|
2226
|
-
border-top: 11px solid rgba(255, 255, 255, 0.08);
|
|
2227
|
-
z-index: -1;
|
|
2228
|
-
}
|
|
2229
|
-
|
|
2230
|
-
/* Enhanced tooltip animations - Only show via JavaScript, not CSS hover */
|
|
2231
|
-
.uvf-time-tooltip.show {
|
|
2232
|
-
opacity: 1 !important;
|
|
2233
|
-
transform: translateX(-50%) translateY(-2px) scale(1) !important;
|
|
2234
|
-
}
|
|
2235
|
-
|
|
2236
|
-
/* Tooltip pulse animation on first hover */
|
|
2237
|
-
@keyframes tooltipPulse {
|
|
2238
|
-
0% { transform: translateX(-50%) translateY(-2px) scale(1); }
|
|
2239
|
-
50% { transform: translateX(-50%) translateY(-4px) scale(1.05); }
|
|
2240
|
-
100% { transform: translateX(-50%) translateY(-2px) scale(1); }
|
|
2241
|
-
}
|
|
2242
|
-
|
|
2243
|
-
.uvf-time-tooltip.pulse {
|
|
2244
|
-
animation: tooltipPulse 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) once;
|
|
2245
|
-
}
|
|
2246
2103
|
|
|
2247
2104
|
/* Mobile responsive design with enhanced touch targets */
|
|
2248
2105
|
@media (max-width: 768px) {
|
|
@@ -2258,51 +2115,8 @@ export class WebPlayer extends BasePlayer {
|
|
|
2258
2115
|
height: 5px;
|
|
2259
2116
|
}
|
|
2260
2117
|
|
|
2261
|
-
.uvf-progress-handle {
|
|
2262
|
-
width: 18px;
|
|
2263
|
-
height: 18px;
|
|
2264
|
-
opacity: 0.8; /* More visible on mobile for discoverability */
|
|
2265
|
-
border-width: 3px;
|
|
2266
|
-
box-shadow:
|
|
2267
|
-
0 0 0 2px rgba(255, 87, 34, 0.3),
|
|
2268
|
-
0 6px 16px rgba(0, 0, 0, 0.3),
|
|
2269
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.5);
|
|
2270
|
-
}
|
|
2271
|
-
|
|
2272
|
-
.uvf-progress-bar-wrapper:hover .uvf-progress-handle,
|
|
2273
|
-
.uvf-progress-handle:active {
|
|
2274
|
-
opacity: 1;
|
|
2275
|
-
transform: translate(-50%, -50%) scale(1);
|
|
2276
|
-
}
|
|
2277
|
-
|
|
2278
|
-
.uvf-progress-handle:hover {
|
|
2279
|
-
transform: translate(-50%, -50%) scale(1.15);
|
|
2280
|
-
box-shadow:
|
|
2281
|
-
0 0 0 4px rgba(255, 87, 34, 0.4),
|
|
2282
|
-
0 8px 20px rgba(255, 87, 34, 0.35),
|
|
2283
|
-
inset 0 2px 0 rgba(255, 255, 255, 0.7);
|
|
2284
|
-
}
|
|
2285
|
-
|
|
2286
|
-
.uvf-progress-handle:active,
|
|
2287
|
-
.uvf-progress-handle.dragging {
|
|
2288
|
-
transform: translate(-50%, -50%) scale(1.3);
|
|
2289
|
-
box-shadow:
|
|
2290
|
-
0 0 0 6px rgba(255, 87, 34, 0.5),
|
|
2291
|
-
0 10px 25px rgba(255, 69, 0, 0.4),
|
|
2292
|
-
inset 0 2px 0 rgba(255, 255, 255, 0.8);
|
|
2293
|
-
}
|
|
2294
2118
|
}
|
|
2295
2119
|
|
|
2296
|
-
/* High DPI displays optimization */
|
|
2297
|
-
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
|
|
2298
|
-
.uvf-progress-handle {
|
|
2299
|
-
background: radial-gradient(circle,
|
|
2300
|
-
rgba(255, 255, 255, 0.98) 0%,
|
|
2301
|
-
rgba(255, 255, 255, 0.92) 70%,
|
|
2302
|
-
rgba(255, 255, 255, 0.88) 100%
|
|
2303
|
-
);
|
|
2304
|
-
}
|
|
2305
|
-
}
|
|
2306
2120
|
/* Controls Row */
|
|
2307
2121
|
.uvf-controls-row {
|
|
2308
2122
|
display: flex;
|
|
@@ -4204,15 +4018,7 @@ export class WebPlayer extends BasePlayer {
|
|
|
4204
4018
|
<div class="uvf-progress-bar">
|
|
4205
4019
|
<div class="uvf-progress-buffered" id="uvf-progress-buffered"></div>
|
|
4206
4020
|
<div class="uvf-progress-filled" id="uvf-progress-filled"></div>
|
|
4207
|
-
<div class="uvf-progress-handle" id="uvf-progress-handle"
|
|
4208
|
-
role="slider"
|
|
4209
|
-
tabindex="0"
|
|
4210
|
-
aria-label="Seek"
|
|
4211
|
-
aria-valuemin="0"
|
|
4212
|
-
aria-valuemax="100"
|
|
4213
|
-
aria-valuenow="0"></div>
|
|
4214
4021
|
</div>
|
|
4215
|
-
<div class="uvf-time-tooltip" id="uvf-time-tooltip">00:00</div>
|
|
4216
4022
|
`;
|
|
4217
4023
|
progressSection.appendChild(progressBar);
|
|
4218
4024
|
|
|
@@ -4483,77 +4289,16 @@ export class WebPlayer extends BasePlayer {
|
|
|
4483
4289
|
});
|
|
4484
4290
|
|
|
4485
4291
|
|
|
4486
|
-
// Enhanced progress bar interactions
|
|
4487
|
-
const progressHandle = document.getElementById('uvf-progress-handle') as HTMLElement;
|
|
4488
|
-
const timeTooltip = document.getElementById('uvf-time-tooltip') as HTMLElement;
|
|
4489
|
-
|
|
4490
4292
|
// Progress bar click
|
|
4491
4293
|
progressBar?.addEventListener('click', (e) => {
|
|
4492
|
-
|
|
4493
|
-
this.handleProgressChange(e as MouseEvent);
|
|
4494
|
-
}
|
|
4495
|
-
});
|
|
4496
|
-
|
|
4497
|
-
// Handle dragging
|
|
4498
|
-
progressHandle?.addEventListener('mousedown', (e) => {
|
|
4499
|
-
e.stopPropagation();
|
|
4500
|
-
this.isDragging = true;
|
|
4501
|
-
progressHandle.classList.add('dragging');
|
|
4502
|
-
});
|
|
4503
|
-
|
|
4504
|
-
// Keyboard support for handle
|
|
4505
|
-
progressHandle?.addEventListener('keydown', (e) => {
|
|
4506
|
-
if (!this.video) return;
|
|
4507
|
-
|
|
4508
|
-
const step = 5; // 5 seconds
|
|
4509
|
-
let handled = false;
|
|
4510
|
-
|
|
4511
|
-
switch(e.key) {
|
|
4512
|
-
case 'ArrowLeft':
|
|
4513
|
-
case 'ArrowDown':
|
|
4514
|
-
this.seek(Math.max(0, this.video.currentTime - step));
|
|
4515
|
-
handled = true;
|
|
4516
|
-
break;
|
|
4517
|
-
case 'ArrowRight':
|
|
4518
|
-
case 'ArrowUp':
|
|
4519
|
-
this.seek(Math.min(this.video.duration, this.video.currentTime + step));
|
|
4520
|
-
handled = true;
|
|
4521
|
-
break;
|
|
4522
|
-
}
|
|
4523
|
-
|
|
4524
|
-
if (handled) {
|
|
4525
|
-
e.preventDefault();
|
|
4526
|
-
e.stopPropagation();
|
|
4527
|
-
}
|
|
4294
|
+
this.handleProgressChange(e as MouseEvent);
|
|
4528
4295
|
});
|
|
4529
4296
|
|
|
4530
4297
|
progressBar?.addEventListener('mousedown', (e) => {
|
|
4531
|
-
if (e.target === progressHandle) return;
|
|
4532
4298
|
this.isDragging = true;
|
|
4533
4299
|
this.handleProgressChange(e as MouseEvent);
|
|
4534
4300
|
});
|
|
4535
4301
|
|
|
4536
|
-
// Progress bar hover events for tooltip
|
|
4537
|
-
progressBar?.addEventListener('mouseenter', () => {
|
|
4538
|
-
const timeTooltip = document.getElementById('uvf-time-tooltip');
|
|
4539
|
-
if (timeTooltip) {
|
|
4540
|
-
timeTooltip.classList.add('show');
|
|
4541
|
-
}
|
|
4542
|
-
});
|
|
4543
|
-
|
|
4544
|
-
progressBar?.addEventListener('mouseleave', () => {
|
|
4545
|
-
if (!this.isDragging) {
|
|
4546
|
-
this.hideTimeTooltip();
|
|
4547
|
-
}
|
|
4548
|
-
});
|
|
4549
|
-
|
|
4550
|
-
// Mouse move handler for progress bar tooltip and dragging
|
|
4551
|
-
progressBar?.addEventListener('mousemove', (e) => {
|
|
4552
|
-
if (!this.isDragging) {
|
|
4553
|
-
this.updateTimeTooltip(e as MouseEvent);
|
|
4554
|
-
}
|
|
4555
|
-
});
|
|
4556
|
-
|
|
4557
4302
|
// Global mouse events for enhanced dragging
|
|
4558
4303
|
document.addEventListener('mousemove', (e) => {
|
|
4559
4304
|
if (this.isVolumeSliding) {
|
|
@@ -4561,7 +4306,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
4561
4306
|
}
|
|
4562
4307
|
if (this.isDragging && progressBar) {
|
|
4563
4308
|
this.handleProgressChange(e);
|
|
4564
|
-
this.updateProgressTooltip(e);
|
|
4565
4309
|
}
|
|
4566
4310
|
});
|
|
4567
4311
|
|
|
@@ -4577,26 +4321,16 @@ export class WebPlayer extends BasePlayer {
|
|
|
4577
4321
|
|
|
4578
4322
|
if (this.isDragging) {
|
|
4579
4323
|
this.isDragging = false;
|
|
4580
|
-
progressHandle?.classList.remove('dragging');
|
|
4581
|
-
// Hide tooltip after dragging ends
|
|
4582
|
-
this.hideTimeTooltip();
|
|
4583
4324
|
}
|
|
4584
4325
|
});
|
|
4585
4326
|
|
|
4586
4327
|
// Update progress bar
|
|
4587
4328
|
this.video.addEventListener('timeupdate', () => {
|
|
4588
4329
|
const progressFilled = document.getElementById('uvf-progress-filled') as HTMLElement;
|
|
4589
|
-
const progressHandle = document.getElementById('uvf-progress-handle') as HTMLElement;
|
|
4590
4330
|
|
|
4591
|
-
if (this.video && progressFilled
|
|
4331
|
+
if (this.video && progressFilled) {
|
|
4592
4332
|
const percent = (this.video.currentTime / this.video.duration) * 100;
|
|
4593
4333
|
progressFilled.style.width = percent + '%';
|
|
4594
|
-
|
|
4595
|
-
// Position handle at the progress position
|
|
4596
|
-
progressHandle.style.left = percent + '%';
|
|
4597
|
-
|
|
4598
|
-
// Update handle aria-valuenow for accessibility
|
|
4599
|
-
progressHandle.setAttribute('aria-valuenow', percent.toString());
|
|
4600
4334
|
}
|
|
4601
4335
|
|
|
4602
4336
|
// Update time display using the dedicated method
|
|
@@ -5338,63 +5072,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
5338
5072
|
}
|
|
5339
5073
|
}
|
|
5340
5074
|
|
|
5341
|
-
private updateTimeTooltip(e: MouseEvent): void {
|
|
5342
|
-
const progressBar = document.getElementById('uvf-progress-bar');
|
|
5343
|
-
const timeTooltip = document.getElementById('uvf-time-tooltip');
|
|
5344
|
-
if (!progressBar || !timeTooltip || !this.video) return;
|
|
5345
|
-
|
|
5346
|
-
// Get the progress bar wrapper's rect for positioning calculations
|
|
5347
|
-
const rect = progressBar.getBoundingClientRect();
|
|
5348
|
-
const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width));
|
|
5349
|
-
const percent = (x / rect.width) * 100;
|
|
5350
|
-
const time = (percent / 100) * this.video.duration;
|
|
5351
|
-
|
|
5352
|
-
// Update tooltip content and position
|
|
5353
|
-
timeTooltip.textContent = this.formatTime(time);
|
|
5354
|
-
timeTooltip.style.left = percent + '%';
|
|
5355
|
-
timeTooltip.classList.add('show');
|
|
5356
|
-
|
|
5357
|
-
// Add pulse animation on first hover
|
|
5358
|
-
if (!timeTooltip.classList.contains('pulse') && timeTooltip.classList.contains('show')) {
|
|
5359
|
-
timeTooltip.classList.add('pulse');
|
|
5360
|
-
setTimeout(() => {
|
|
5361
|
-
timeTooltip.classList.remove('pulse');
|
|
5362
|
-
}, 600);
|
|
5363
|
-
}
|
|
5364
|
-
}
|
|
5365
|
-
|
|
5366
|
-
private hideTimeTooltip(): void {
|
|
5367
|
-
const timeTooltip = document.getElementById('uvf-time-tooltip');
|
|
5368
|
-
if (timeTooltip) {
|
|
5369
|
-
timeTooltip.classList.remove('show');
|
|
5370
|
-
// Remove any inline opacity style to let CSS handle it
|
|
5371
|
-
timeTooltip.style.removeProperty('opacity');
|
|
5372
|
-
}
|
|
5373
|
-
}
|
|
5374
|
-
|
|
5375
|
-
private updateProgressTooltip(e: MouseEvent): void {
|
|
5376
|
-
const progressBar = document.getElementById('uvf-progress-bar');
|
|
5377
|
-
const timeTooltip = document.getElementById('uvf-time-tooltip');
|
|
5378
|
-
const progressHandle = document.getElementById('uvf-progress-handle');
|
|
5379
|
-
if (!progressBar || !timeTooltip || !this.video) return;
|
|
5380
|
-
|
|
5381
|
-
// Get the progress bar wrapper's rect for positioning calculations
|
|
5382
|
-
const rect = progressBar.getBoundingClientRect();
|
|
5383
|
-
const position = Math.max(0, Math.min(e.clientX - rect.left, rect.width));
|
|
5384
|
-
const percent = (position / rect.width) * 100;
|
|
5385
|
-
const time = (percent / 100) * this.video.duration;
|
|
5386
|
-
|
|
5387
|
-
// Update tooltip content and position
|
|
5388
|
-
timeTooltip.textContent = this.formatTime(time);
|
|
5389
|
-
timeTooltip.style.left = percent + '%';
|
|
5390
|
-
timeTooltip.classList.add('show');
|
|
5391
|
-
|
|
5392
|
-
// Add visual feedback during dragging
|
|
5393
|
-
if (progressHandle && this.isDragging) {
|
|
5394
|
-
progressHandle.style.transform = 'translate(-50%, -50%) scale(1.4)';
|
|
5395
|
-
progressHandle.classList.add('dragging');
|
|
5396
|
-
}
|
|
5397
|
-
}
|
|
5398
5075
|
|
|
5399
5076
|
|
|
5400
5077
|
private showShortcutIndicator(text: string): void {
|