@codercms/web-player 0.0.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/LICENSE +21 -0
- package/README.md +3 -0
- package/dist/HybridDoublyLinkedList.d.ts +20 -0
- package/dist/HybridDoublyLinkedList.js +90 -0
- package/dist/HybridDoublyLinkedList.js.map +1 -0
- package/dist/HybridLinkedList.d.ts +18 -0
- package/dist/HybridLinkedList.js +90 -0
- package/dist/HybridLinkedList.js.map +1 -0
- package/dist/core/HLSLoader.d.ts +18 -0
- package/dist/core/HLSLoader.js +144 -0
- package/dist/core/HLSLoader.js.map +1 -0
- package/dist/core/LoaderInterface.d.ts +37 -0
- package/dist/core/LoaderInterface.js +27 -0
- package/dist/core/LoaderInterface.js.map +1 -0
- package/dist/core/Playlist.d.ts +60 -0
- package/dist/core/Playlist.js +141 -0
- package/dist/core/Playlist.js.map +1 -0
- package/dist/core/PlaylistPlayer.d.ts +29 -0
- package/dist/core/PlaylistPlayer.js +82 -0
- package/dist/core/PlaylistPlayer.js.map +1 -0
- package/dist/core/QualityLevel.d.ts +7 -0
- package/dist/core/QualityLevel.js +1 -0
- package/dist/core/QualityLevel.js.map +1 -0
- package/dist/core/VideoPlayer.d.ts +104 -0
- package/dist/core/VideoPlayer.js +342 -0
- package/dist/core/VideoPlayer.js.map +1 -0
- package/dist/index.d.ts +0 -0
- package/dist/index.js +1 -0
- package/dist/ui/LoadingIndicator.svelte +74 -0
- package/dist/ui/LoadingIndicator.svelte.d.ts +18 -0
- package/dist/ui/ProgressBar.svelte +283 -0
- package/dist/ui/ProgressBar.svelte.d.ts +17 -0
- package/dist/ui/utils/duration.d.ts +1 -0
- package/dist/ui/utils/duration.js +23 -0
- package/dist/ui/utils/duration.js.map +1 -0
- package/dist/ui/utils/slider.d.ts +25 -0
- package/dist/ui/utils/slider.js +132 -0
- package/dist/ui/utils/slider.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
<script>import { PlayerEvents } from "../core/VideoPlayer";
|
|
2
|
+
import { LoaderEvents } from "../core/LoaderInterface";
|
|
3
|
+
import { onMount } from "svelte";
|
|
4
|
+
import {
|
|
5
|
+
getValueByMousePos,
|
|
6
|
+
getValueForDragEvent,
|
|
7
|
+
normalizePointerPos,
|
|
8
|
+
draggableAction
|
|
9
|
+
} from "./utils/slider";
|
|
10
|
+
import { toDuration } from "./utils/duration";
|
|
11
|
+
export let player;
|
|
12
|
+
let selfEl;
|
|
13
|
+
let currentTime = 0;
|
|
14
|
+
let duration = 0;
|
|
15
|
+
let buffered = [];
|
|
16
|
+
let currentTImeOffset = 0;
|
|
17
|
+
let isDragging = false;
|
|
18
|
+
let draggingTime;
|
|
19
|
+
let relCurrentTime = 0;
|
|
20
|
+
$:
|
|
21
|
+
if (!isDragging && currentTime > 0 && duration > 0) {
|
|
22
|
+
currentTImeOffset = currentTime / duration;
|
|
23
|
+
relCurrentTime = currentTime;
|
|
24
|
+
}
|
|
25
|
+
$:
|
|
26
|
+
if (isDragging && duration > 0) {
|
|
27
|
+
currentTImeOffset = draggingTime / duration;
|
|
28
|
+
relCurrentTime = draggingTime;
|
|
29
|
+
}
|
|
30
|
+
let tooltipVisible = false;
|
|
31
|
+
$:
|
|
32
|
+
relTooltipVisible = tooltipVisible || isDragging;
|
|
33
|
+
let tooltipEl;
|
|
34
|
+
let tooltipTime = 0;
|
|
35
|
+
let tooltipDurationText = "";
|
|
36
|
+
let tooltipWidth = 0;
|
|
37
|
+
onMount(() => {
|
|
38
|
+
currentTime = player.currentTime;
|
|
39
|
+
duration = player.duration;
|
|
40
|
+
buffered = player.buffered;
|
|
41
|
+
player.subscribe(PlayerEvents.PlaybackDurationChange, (newDuration) => {
|
|
42
|
+
duration = newDuration;
|
|
43
|
+
});
|
|
44
|
+
player.subscribe(PlayerEvents.PlaybackTimeUpdate, (newCurrentTime) => {
|
|
45
|
+
currentTime = newCurrentTime;
|
|
46
|
+
});
|
|
47
|
+
player.subscribe(PlayerEvents.PlaybackBufferingProgress, (newBuffered) => {
|
|
48
|
+
buffered = newBuffered;
|
|
49
|
+
});
|
|
50
|
+
player.subscribe(LoaderEvents.Loading, () => {
|
|
51
|
+
currentTime = 0;
|
|
52
|
+
duration = 0;
|
|
53
|
+
currentTImeOffset = 0;
|
|
54
|
+
buffered = [];
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
const seekToPosition = (e) => {
|
|
58
|
+
if (duration === 0) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const clickPos = normalizePointerPos(e);
|
|
62
|
+
let clickValue = getValueByMousePos(clickPos, duration, selfEl);
|
|
63
|
+
player.seekTo(clickValue);
|
|
64
|
+
};
|
|
65
|
+
const handleDragStart = (e) => {
|
|
66
|
+
if (duration === 0) {
|
|
67
|
+
e.preventDefault();
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
isDragging = true;
|
|
71
|
+
};
|
|
72
|
+
const handleDragging = (e) => {
|
|
73
|
+
draggingTime = getValueForDragEvent(selfEl, e.detail.pos, 0, duration, {
|
|
74
|
+
step: 0.1,
|
|
75
|
+
precision: 1
|
|
76
|
+
});
|
|
77
|
+
tooltipTime = draggingTime;
|
|
78
|
+
tooltipDurationText = toDuration(draggingTime);
|
|
79
|
+
tooltipWidth = tooltipEl.clientWidth;
|
|
80
|
+
};
|
|
81
|
+
const resetDragging = () => {
|
|
82
|
+
isDragging = false;
|
|
83
|
+
draggingTime = 0;
|
|
84
|
+
};
|
|
85
|
+
const handleDragEnd = (e) => {
|
|
86
|
+
player.seekTo(draggingTime);
|
|
87
|
+
currentTime = draggingTime;
|
|
88
|
+
resetDragging();
|
|
89
|
+
};
|
|
90
|
+
const handleDragCancel = (e) => {
|
|
91
|
+
resetDragging();
|
|
92
|
+
};
|
|
93
|
+
const handleTooltipPointerMove = (e) => {
|
|
94
|
+
if (duration <= 0 || !isFinite(duration)) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const pointerPos = normalizePointerPos(e);
|
|
98
|
+
const time = getValueByMousePos(pointerPos, duration, selfEl);
|
|
99
|
+
tooltipTime = time;
|
|
100
|
+
tooltipDurationText = toDuration(time);
|
|
101
|
+
tooltipWidth = tooltipEl.clientWidth;
|
|
102
|
+
tooltipVisible = true;
|
|
103
|
+
};
|
|
104
|
+
const handlePointerLeave = () => {
|
|
105
|
+
tooltipVisible = false;
|
|
106
|
+
};
|
|
107
|
+
</script>
|
|
108
|
+
|
|
109
|
+
<div
|
|
110
|
+
class="progress-bar"
|
|
111
|
+
role="progressbar"
|
|
112
|
+
tabindex="0"
|
|
113
|
+
bind:this={selfEl}
|
|
114
|
+
use:draggableAction
|
|
115
|
+
on:s-dragstart={handleDragStart}
|
|
116
|
+
on:s-dragend={handleDragEnd}
|
|
117
|
+
on:s-dragcancel={handleDragCancel}
|
|
118
|
+
on:s-dragging={handleDragging}
|
|
119
|
+
on:mousemove={handleTooltipPointerMove}
|
|
120
|
+
on:mouseleave={handlePointerLeave}
|
|
121
|
+
on:touchmove={handleTooltipPointerMove}
|
|
122
|
+
on:touchend={handlePointerLeave}
|
|
123
|
+
>
|
|
124
|
+
<div class="full-width-bar" />
|
|
125
|
+
|
|
126
|
+
<div style="overflow-x: clip;">
|
|
127
|
+
<div
|
|
128
|
+
class="tooltip-container"
|
|
129
|
+
style:opacity={relTooltipVisible ? `1` : `0`}
|
|
130
|
+
style:--offset="{(tooltipTime / duration) * 100}%"
|
|
131
|
+
style:--ch-length="{tooltipWidth / 2}px"
|
|
132
|
+
>
|
|
133
|
+
<div class="tooltip" bind:this={tooltipEl}>
|
|
134
|
+
<span class="tooltip-time">{tooltipDurationText}</span>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
<div class="buffered-parts">
|
|
140
|
+
{#if duration > 0}
|
|
141
|
+
{#each buffered as range (range.start)}
|
|
142
|
+
<!-- Cut buffered part start to prevent overlap with current time line -->
|
|
143
|
+
{@const startCut = range.start < relCurrentTime ? relCurrentTime : range.start}
|
|
144
|
+
<!-- Prevent buffered part overlap with current time line -->
|
|
145
|
+
{@const isVisible = range.end > relCurrentTime}
|
|
146
|
+
|
|
147
|
+
<div
|
|
148
|
+
class="buffered-part"
|
|
149
|
+
style:visibility={isVisible ? 'visible' : 'hidden'}
|
|
150
|
+
style:--buf-part-start={isVisible ? `${(startCut / duration) * 100}%` : `0`}
|
|
151
|
+
style:--buf-part-offset={isVisible ? (range.end - startCut) / duration : 0}
|
|
152
|
+
/>
|
|
153
|
+
{/each}
|
|
154
|
+
{/if}
|
|
155
|
+
</div>
|
|
156
|
+
|
|
157
|
+
<div class="current-time-line-container">
|
|
158
|
+
<div class="current-time-line" style:--current-time-offest={currentTImeOffset} />
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
|
|
162
|
+
<style>
|
|
163
|
+
:root {
|
|
164
|
+
--defaultScaleBarsY: 1.45;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.progress-bar {
|
|
168
|
+
position: relative;
|
|
169
|
+
width: 100%;
|
|
170
|
+
height: var(--player-progress-bar-height, 10px);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.progress-bar .full-width-bar {
|
|
174
|
+
position: absolute;
|
|
175
|
+
left: 0;
|
|
176
|
+
top: 0;
|
|
177
|
+
width: 100%;
|
|
178
|
+
height: 100%;
|
|
179
|
+
|
|
180
|
+
/*background-color: rgba(121, 117, 117, 0.9);*/
|
|
181
|
+
background-color: hsla(0, 0%, 100%, 0.3);
|
|
182
|
+
|
|
183
|
+
transform-origin: bottom center;
|
|
184
|
+
transform: scaleY(var(--scaleBarsY, 1));
|
|
185
|
+
transition: transform 0.3s ease;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.progress-bar:hover > .current-time-line-container {
|
|
189
|
+
--scaleBarsY: var(--player-progress-bar-scale-on-hover, var(--defaultScaleBarsY));
|
|
190
|
+
}
|
|
191
|
+
.progress-bar:hover > .buffered-parts {
|
|
192
|
+
--scaleBarsY: var(--player-progress-bar-scale-on-hover, var(--defaultScaleBarsY));
|
|
193
|
+
}
|
|
194
|
+
.progress-bar:hover > .full-width-bar {
|
|
195
|
+
--scaleBarsY: var(--player-progress-bar-scale-on-hover, var(--defaultScaleBarsY));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.buffered-parts {
|
|
199
|
+
position: absolute;
|
|
200
|
+
top: 0;
|
|
201
|
+
bottom: 0;
|
|
202
|
+
width: 100%;
|
|
203
|
+
|
|
204
|
+
transform-origin: bottom center;
|
|
205
|
+
transform: scaleY(var(--scaleBarsY, 1));
|
|
206
|
+
transition: transform 0.3s ease;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.buffered-parts .buffered-part {
|
|
210
|
+
position: absolute;
|
|
211
|
+
top: 0;
|
|
212
|
+
/*bottom: 0;*/
|
|
213
|
+
left: var(--buf-part-start, 0);
|
|
214
|
+
height: 100%;
|
|
215
|
+
width: 100%;
|
|
216
|
+
|
|
217
|
+
transform-origin: left center;
|
|
218
|
+
transform: scaleX(calc(100% * var(--buf-part-offset, 0)));
|
|
219
|
+
|
|
220
|
+
z-index: 10; /* Place the buffered parts behind the current time line */
|
|
221
|
+
/*background-color: rgba(0, 0, 255, 0.3); !* Adjust the color and opacity as needed *!*/
|
|
222
|
+
background-color: hsla(0, 0%, 100%, 0.4);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.current-time-line-container {
|
|
226
|
+
position: absolute;
|
|
227
|
+
left: 0;
|
|
228
|
+
top: 0;
|
|
229
|
+
width: 100%;
|
|
230
|
+
height: 100%;
|
|
231
|
+
|
|
232
|
+
transform-origin: bottom center;
|
|
233
|
+
transform: scaleY(var(--scaleBarsY, 1));
|
|
234
|
+
transition: transform 0.3s ease;
|
|
235
|
+
|
|
236
|
+
z-index: 20;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.current-time-line-container .current-time-line {
|
|
240
|
+
width: 100%;
|
|
241
|
+
height: 100%;
|
|
242
|
+
|
|
243
|
+
transform-origin: left center;
|
|
244
|
+
/*transform: scaleX(calc(100% * var(--current-time-offest, 0)));*/
|
|
245
|
+
transform: scale3d(calc(100% * var(--current-time-offest, 0)), 1, 1);
|
|
246
|
+
|
|
247
|
+
background-color: rgba(255, 85, 0, 0.8);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.tooltip-container {
|
|
251
|
+
width: 100%;
|
|
252
|
+
opacity: 0;
|
|
253
|
+
transition: opacity 0.2s ease-in-out;
|
|
254
|
+
transform: translate3d(
|
|
255
|
+
min(
|
|
256
|
+
/* minimum offset from left */ max(var(--offset), var(--ch-length)),
|
|
257
|
+
/* maximum offset to right */ calc(100% - var(--ch-length))
|
|
258
|
+
),
|
|
259
|
+
0,
|
|
260
|
+
0
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
z-index: 20;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.tooltip-container .tooltip {
|
|
267
|
+
position: absolute;
|
|
268
|
+
top: -30px;
|
|
269
|
+
left: 0;
|
|
270
|
+
|
|
271
|
+
transform: translate(-50%, 0);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.tooltip-container .tooltip span.tooltip-time {
|
|
275
|
+
background-color: rgba(73, 71, 71, 0.7);
|
|
276
|
+
color: white;
|
|
277
|
+
padding: 4px 8px;
|
|
278
|
+
border-radius: 4px;
|
|
279
|
+
white-space: nowrap;
|
|
280
|
+
font-size: 14px;
|
|
281
|
+
user-select: none;
|
|
282
|
+
}
|
|
283
|
+
</style>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { VideoPlayer } from '../core/VideoPlayer';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
player: VideoPlayer;
|
|
6
|
+
};
|
|
7
|
+
events: {
|
|
8
|
+
[evt: string]: CustomEvent<any>;
|
|
9
|
+
};
|
|
10
|
+
slots: {};
|
|
11
|
+
};
|
|
12
|
+
export type ProgressBarProps = typeof __propDef.props;
|
|
13
|
+
export type ProgressBarEvents = typeof __propDef.events;
|
|
14
|
+
export type ProgressBarSlots = typeof __propDef.slots;
|
|
15
|
+
export default class ProgressBar extends SvelteComponent<ProgressBarProps, ProgressBarEvents, ProgressBarSlots> {
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function toDuration(sec_num: number): string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function toDuration(sec_num) {
|
|
2
|
+
const hours = Math.floor(sec_num / 3600);
|
|
3
|
+
const minutes = Math.floor((sec_num - hours * 3600) / 60);
|
|
4
|
+
const seconds = Math.floor(sec_num - hours * 3600 - minutes * 60);
|
|
5
|
+
let minutesTxt, secondsTxt;
|
|
6
|
+
const hoursTxt = `${hours}`;
|
|
7
|
+
if (minutes < 10) {
|
|
8
|
+
minutesTxt = `0${minutes}`;
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
minutesTxt = String(minutes);
|
|
12
|
+
}
|
|
13
|
+
if (seconds < 10) {
|
|
14
|
+
secondsTxt = `0${seconds}`;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
secondsTxt = String(seconds);
|
|
18
|
+
}
|
|
19
|
+
if (hours < 1) {
|
|
20
|
+
return `${minutesTxt}:${secondsTxt}`;
|
|
21
|
+
}
|
|
22
|
+
return `${hoursTxt}:${minutesTxt}:${secondsTxt}`;
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duration.js","sourceRoot":"","sources":["duration.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,UAAU,CAAC,OAAe;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,GAAG,IAAI,GAAG,OAAO,GAAG,EAAE,CAAC,CAAC;IAElE,IAAI,UAAU,EAAE,UAAkB,CAAC;IAEnC,MAAM,QAAQ,GAAG,GAAG,KAAK,EAAE,CAAC;IAE5B,IAAI,OAAO,GAAG,EAAE,EAAE;QACjB,UAAU,GAAG,IAAI,OAAO,EAAE,CAAC;KAC3B;SAAM;QACN,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;KAC7B;IAED,IAAI,OAAO,GAAG,EAAE,EAAE;QACjB,UAAU,GAAG,IAAI,OAAO,EAAE,CAAC;KAC3B;SAAM;QACN,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;KAC7B;IAED,IAAI,KAAK,GAAG,CAAC,EAAE;QACd,OAAO,GAAG,UAAU,IAAI,UAAU,EAAE,CAAC;KACrC;IAED,OAAO,GAAG,QAAQ,IAAI,UAAU,IAAI,UAAU,EAAE,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Action } from 'svelte/action';
|
|
2
|
+
import type { Element } from 'svelte/types/compiler/interfaces';
|
|
3
|
+
export type MousePos = {
|
|
4
|
+
clientX: number;
|
|
5
|
+
clientY: number;
|
|
6
|
+
};
|
|
7
|
+
export declare function normalizePointerPos(e: MouseEvent | TouchEvent): MousePos;
|
|
8
|
+
export declare function getWidthByValue(max: number, value: number, slider: Element): number;
|
|
9
|
+
export declare function getValueByWidth(max: number, width: number): number;
|
|
10
|
+
export declare function getValueByMousePos(pos: MousePos, max: number, slider: HTMLElement): number;
|
|
11
|
+
export declare function getValueForDragEvent(slider: HTMLElement, dragPosition: MousePos, min: number, max: number, step?: AlignStep): number;
|
|
12
|
+
export type AlignStep = {
|
|
13
|
+
step: number;
|
|
14
|
+
precision: number;
|
|
15
|
+
};
|
|
16
|
+
export type DraggingEventParams = {
|
|
17
|
+
pos: MousePos;
|
|
18
|
+
ev: MouseEvent | TouchEvent;
|
|
19
|
+
};
|
|
20
|
+
export declare const draggableAction: Action<HTMLElement, unknown, {
|
|
21
|
+
'on:s-dragstart': (e: CustomEvent<never>) => void;
|
|
22
|
+
'on:s-dragend': (e: CustomEvent<never>) => void;
|
|
23
|
+
'on:s-dragcancel': (e: CustomEvent<never>) => void;
|
|
24
|
+
'on:s-dragging': (e: CustomEvent<DraggingEventParams>) => void;
|
|
25
|
+
}>;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
export function normalizePointerPos(e) {
|
|
2
|
+
if ('touches' in e) {
|
|
3
|
+
const touch = e.touches[0];
|
|
4
|
+
return {
|
|
5
|
+
clientX: touch.clientX,
|
|
6
|
+
clientY: touch.clientY
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
if ('clientX' in e) {
|
|
10
|
+
return {
|
|
11
|
+
clientX: e.clientX,
|
|
12
|
+
clientY: e.clientY
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
throw new Error('Slider::normalizePointerPos unknown event passed');
|
|
16
|
+
}
|
|
17
|
+
export function getWidthByValue(max, value, slider) {
|
|
18
|
+
if (max <= 0 || !isFinite(max)) {
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
if (value <= 0 || !isFinite(value)) {
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
if (!slider) {
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
const rect = slider.getBoundingClientRect();
|
|
28
|
+
const coeff = max / value;
|
|
29
|
+
return rect.width / coeff;
|
|
30
|
+
}
|
|
31
|
+
export function getValueByWidth(max, width) {
|
|
32
|
+
if (max <= 0 || !isFinite(max) || width <= 0 || !isFinite(width)) {
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
return max / width;
|
|
36
|
+
}
|
|
37
|
+
export function getValueByMousePos(pos, max, slider) {
|
|
38
|
+
if (max <= 0 || !isFinite(max)) {
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
if (!slider) {
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
const rect = slider.getBoundingClientRect();
|
|
45
|
+
const relativeOffset = pos.clientX - rect.left;
|
|
46
|
+
const coeff = relativeOffset / rect.width;
|
|
47
|
+
return max * coeff;
|
|
48
|
+
}
|
|
49
|
+
export function getValueForDragEvent(slider, dragPosition, min, max, step) {
|
|
50
|
+
let clickValue = getValueByMousePos(dragPosition, max, slider);
|
|
51
|
+
if (clickValue > max) {
|
|
52
|
+
clickValue = max;
|
|
53
|
+
}
|
|
54
|
+
else if (clickValue < min) {
|
|
55
|
+
clickValue = min;
|
|
56
|
+
}
|
|
57
|
+
if (step) {
|
|
58
|
+
clickValue = alignValueToStep(clickValue, min, step);
|
|
59
|
+
}
|
|
60
|
+
return clickValue;
|
|
61
|
+
}
|
|
62
|
+
const fixFloat = (v, precision) => parseFloat(v.toFixed(precision));
|
|
63
|
+
const alignValueToStep = (val, minValue, step) => {
|
|
64
|
+
// find the middle-point between steps
|
|
65
|
+
// and see if the value is closer to the
|
|
66
|
+
// next step, or previous step
|
|
67
|
+
let remainder = (val - minValue) % step.step;
|
|
68
|
+
let aligned = val - remainder;
|
|
69
|
+
if (Math.abs(remainder) * 2 >= step.step) {
|
|
70
|
+
aligned += remainder > 0 ? step.step : -step.step;
|
|
71
|
+
}
|
|
72
|
+
// make sure the value is within acceptable limits
|
|
73
|
+
// aligned = clampValue(aligned);
|
|
74
|
+
// make sure the returned value is set to the precision desired
|
|
75
|
+
// this is also because javascript often returns weird floats
|
|
76
|
+
// when dealing with odd numbers and percentages
|
|
77
|
+
return fixFloat(aligned, step.precision);
|
|
78
|
+
};
|
|
79
|
+
export const draggableAction = (node) => {
|
|
80
|
+
let isDragging = false;
|
|
81
|
+
const handleKeys = (e) => {
|
|
82
|
+
switch (e.key) {
|
|
83
|
+
case 'Esc':
|
|
84
|
+
case 'Escape':
|
|
85
|
+
resetDragging();
|
|
86
|
+
node.dispatchEvent(new CustomEvent('s-dragcancel'));
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const startDrag = (e) => {
|
|
90
|
+
const ev = new CustomEvent('s-dragstart', { cancelable: true });
|
|
91
|
+
node.dispatchEvent(ev);
|
|
92
|
+
// Dragging was cancelled by component
|
|
93
|
+
if (ev.defaultPrevented) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
isDragging = true;
|
|
97
|
+
handleDrag(e);
|
|
98
|
+
window.addEventListener('mousemove', handleDrag);
|
|
99
|
+
window.addEventListener('mouseup', endDrag);
|
|
100
|
+
window.addEventListener('touchmove', handleDrag, { passive: false });
|
|
101
|
+
window.addEventListener('touchend', endDrag);
|
|
102
|
+
window.addEventListener('keydown', handleKeys);
|
|
103
|
+
};
|
|
104
|
+
// Handle mouse move or touch move events for dragging
|
|
105
|
+
const handleDrag = (e) => {
|
|
106
|
+
if (!isDragging) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const dragPosition = normalizePointerPos(e);
|
|
110
|
+
node.dispatchEvent(new CustomEvent('s-dragging', { detail: { pos: dragPosition, ev: e } }));
|
|
111
|
+
};
|
|
112
|
+
const endDrag = () => {
|
|
113
|
+
node.dispatchEvent(new CustomEvent('s-dragend'));
|
|
114
|
+
resetDragging();
|
|
115
|
+
};
|
|
116
|
+
const resetDragging = () => {
|
|
117
|
+
isDragging = false;
|
|
118
|
+
// If not dragging, remove the event listeners to avoid unnecessary processing
|
|
119
|
+
window.removeEventListener('mousemove', handleDrag);
|
|
120
|
+
window.removeEventListener('mouseup', endDrag);
|
|
121
|
+
window.removeEventListener('touchmove', handleDrag);
|
|
122
|
+
window.removeEventListener('touchend', endDrag);
|
|
123
|
+
window.removeEventListener('keydown', handleKeys);
|
|
124
|
+
};
|
|
125
|
+
node.addEventListener('mousedown', startDrag);
|
|
126
|
+
return {
|
|
127
|
+
destroy: () => {
|
|
128
|
+
node.removeEventListener('mousedown', startDrag);
|
|
129
|
+
resetDragging();
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slider.js","sourceRoot":"","sources":["slider.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@codercms/web-player",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"dev": "vite dev",
|
|
6
|
+
"build": "vite build && npm run package",
|
|
7
|
+
"preview": "vite preview",
|
|
8
|
+
"package": "svelte-kit sync && svelte-package && publint",
|
|
9
|
+
"prepublishOnly": "npm run package",
|
|
10
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
11
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
12
|
+
"test": "vitest",
|
|
13
|
+
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
|
14
|
+
"format": "prettier --plugin-search-dir . --write ."
|
|
15
|
+
},
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"svelte": "./dist/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"!dist/**/*.test.*",
|
|
25
|
+
"!dist/**/*.spec.*"
|
|
26
|
+
],
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"svelte": "^4.0.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@sveltejs/adapter-auto": "^2.0.0",
|
|
32
|
+
"@sveltejs/kit": "^1.20.4",
|
|
33
|
+
"@sveltejs/package": "^2.0.0",
|
|
34
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
35
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
36
|
+
"eslint": "^8.28.0",
|
|
37
|
+
"eslint-config-prettier": "^8.5.0",
|
|
38
|
+
"eslint-plugin-svelte": "^2.30.0",
|
|
39
|
+
"eventemitter3": "^5.0.1",
|
|
40
|
+
"hls.js": "^1.4.12",
|
|
41
|
+
"prettier": "^2.8.0",
|
|
42
|
+
"prettier-plugin-svelte": "^2.10.1",
|
|
43
|
+
"publint": "^0.1.9",
|
|
44
|
+
"svelte": "^4.0.5",
|
|
45
|
+
"svelte-check": "^3.4.3",
|
|
46
|
+
"tslib": "^2.4.1",
|
|
47
|
+
"typescript": "^5.0.0",
|
|
48
|
+
"vite": "^4.4.2",
|
|
49
|
+
"vitest": "^0.34.0"
|
|
50
|
+
},
|
|
51
|
+
"svelte": "./dist/index.js",
|
|
52
|
+
"types": "./dist/index.d.ts",
|
|
53
|
+
"type": "module"
|
|
54
|
+
}
|