@douyinfe/semi-foundation 2.79.0 → 2.80.0-beta.0
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/lib/cjs/videoPlayer/animation.scss +7 -0
- package/lib/cjs/videoPlayer/constants.d.ts +30 -0
- package/lib/cjs/videoPlayer/constants.js +48 -0
- package/lib/cjs/videoPlayer/foundation.d.ts +75 -0
- package/lib/cjs/videoPlayer/foundation.js +291 -0
- package/lib/cjs/videoPlayer/progressFoundation.d.ts +38 -0
- package/lib/cjs/videoPlayer/progressFoundation.js +131 -0
- package/lib/cjs/videoPlayer/variables.scss +75 -0
- package/lib/cjs/videoPlayer/videoPlayer.css +279 -0
- package/lib/cjs/videoPlayer/videoPlayer.scss +323 -0
- package/lib/es/videoPlayer/animation.scss +7 -0
- package/lib/es/videoPlayer/constants.d.ts +30 -0
- package/lib/es/videoPlayer/constants.js +43 -0
- package/lib/es/videoPlayer/foundation.d.ts +75 -0
- package/lib/es/videoPlayer/foundation.js +283 -0
- package/lib/es/videoPlayer/progressFoundation.d.ts +38 -0
- package/lib/es/videoPlayer/progressFoundation.js +123 -0
- package/lib/es/videoPlayer/variables.scss +75 -0
- package/lib/es/videoPlayer/videoPlayer.css +279 -0
- package/lib/es/videoPlayer/videoPlayer.scss +323 -0
- package/package.json +4 -4
- package/videoPlayer/animation.scss +7 -0
- package/videoPlayer/constants.ts +39 -0
- package/videoPlayer/foundation.ts +332 -0
- package/videoPlayer/progressFoundation.ts +136 -0
- package/videoPlayer/variables.scss +75 -0
- package/videoPlayer/videoPlayer.scss +323 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import BaseFoundation, { DefaultAdapter } from '../base/foundation';
|
|
2
|
+
import { numbers } from './constants';
|
|
3
|
+
import { throttle } from 'lodash';
|
|
4
|
+
|
|
5
|
+
export interface VideoPlayerAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
|
|
6
|
+
getVideo: () => HTMLVideoElement | null;
|
|
7
|
+
getVideoWrapper: () => HTMLDivElement | null;
|
|
8
|
+
notifyPause: () => void;
|
|
9
|
+
notifyPlay: () => void;
|
|
10
|
+
notifyQualityChange: (quality: string) => void;
|
|
11
|
+
notifyRateChange: (rate: number) => void;
|
|
12
|
+
notifyRouteChange: (route: string) => void;
|
|
13
|
+
notifyVolumeChange: (volume: number) => void;
|
|
14
|
+
setBufferedValue: (bufferedValue: number) => void;
|
|
15
|
+
setCurrentTime: (currentTime: number) => void;
|
|
16
|
+
setIsError: (isError: boolean) => void;
|
|
17
|
+
setIsMirror: (isMirror: boolean) => void;
|
|
18
|
+
setIsPlaying: (isPlaying: boolean) => void;
|
|
19
|
+
setMuted: (muted: boolean) => void;
|
|
20
|
+
setNotificationContent: (content: string) => void;
|
|
21
|
+
setPlaybackRate: (rate: number) => void;
|
|
22
|
+
setQuality: (quality: string) => void;
|
|
23
|
+
setRoute: (route: string) => void;
|
|
24
|
+
setShowControls: (showControls: boolean) => void;
|
|
25
|
+
setShowNotification: (showNotification: boolean) => void;
|
|
26
|
+
setTotalTime: (totalTime: number) => void;
|
|
27
|
+
setVolume: (volume: number) => void
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default class VideoPlayerFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<VideoPlayerAdapter<P, S>, P, S> {
|
|
31
|
+
constructor(adapter: VideoPlayerAdapter<P, S>) {
|
|
32
|
+
super({ ...adapter });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private controlsTimer: NodeJS.Timeout | null;
|
|
36
|
+
private scrollPosition: { x: number; y: number } | null = null;
|
|
37
|
+
|
|
38
|
+
init() {
|
|
39
|
+
const { volume, muted } = this.getProps();
|
|
40
|
+
const video = this._adapter.getVideo();
|
|
41
|
+
if (video) {
|
|
42
|
+
this._adapter.setTotalTime(video.duration);
|
|
43
|
+
this.handleVolumeChange(muted ? 0 : volume);
|
|
44
|
+
}
|
|
45
|
+
this.registerEvent();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
destroy() {
|
|
49
|
+
this.unregisterEvent();
|
|
50
|
+
this.clearTimer();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
shouldShowControlItem(name: string) {
|
|
54
|
+
const { controlsList } = this.getProps();
|
|
55
|
+
if (controlsList.includes(name)) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
clearTimer() {
|
|
62
|
+
if (this.controlsTimer) {
|
|
63
|
+
clearTimeout(this.controlsTimer);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
handleMouseMove = throttle(() => {
|
|
68
|
+
this._adapter.setShowControls(true);
|
|
69
|
+
this.clearTimer();
|
|
70
|
+
this.controlsTimer = setTimeout(() => {
|
|
71
|
+
this._adapter.setShowControls(false);
|
|
72
|
+
}, 3000);
|
|
73
|
+
}, 200);
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
handleTimeChange(value: number) {
|
|
77
|
+
const video = this._adapter.getVideo();
|
|
78
|
+
if (!video) return;
|
|
79
|
+
if (!Number.isNaN(value)) {
|
|
80
|
+
video.currentTime = value;
|
|
81
|
+
this._adapter.setCurrentTime(value);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
handleTimeUpdate() {
|
|
86
|
+
const video = this._adapter.getVideo();
|
|
87
|
+
if (!video) return;
|
|
88
|
+
this._adapter.setCurrentTime(video.currentTime);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
handleDurationChange() {
|
|
92
|
+
const video = this._adapter.getVideo();
|
|
93
|
+
if (!video) return;
|
|
94
|
+
this._adapter.setTotalTime(video.duration);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
handleError() {
|
|
98
|
+
this._adapter.setIsError(true);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
handlePlayOrPause() {
|
|
102
|
+
const video = this._adapter.getVideo();
|
|
103
|
+
if (!video) return;
|
|
104
|
+
video.paused ? this.handlePlay() : this.handlePause();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
handlePlay() {
|
|
108
|
+
const video = this._adapter.getVideo();
|
|
109
|
+
if (video) {
|
|
110
|
+
video.play();
|
|
111
|
+
this._adapter.setIsPlaying(true);
|
|
112
|
+
this._adapter.notifyPlay();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
handlePause() {
|
|
117
|
+
const video = this._adapter.getVideo();
|
|
118
|
+
if (video) {
|
|
119
|
+
video.pause();
|
|
120
|
+
this._adapter.setIsPlaying(false);
|
|
121
|
+
this._adapter.notifyPause();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
handleCanPlay = () => {
|
|
126
|
+
this._adapter.setShowNotification(false);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
handleWaiting = (locale: any) => {
|
|
130
|
+
this._adapter.setNotificationContent(locale.loading);
|
|
131
|
+
this._adapter.setShowNotification(true);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
handleStalled = (locale: any) => {
|
|
135
|
+
this._adapter.setNotificationContent(locale.stall);
|
|
136
|
+
this._adapter.setShowNotification(true);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
handleProgress = () => {
|
|
140
|
+
const video = this._adapter.getVideo();
|
|
141
|
+
if (video && video.buffered.length > 0) {
|
|
142
|
+
const bufferedEnd = video.buffered.end(video.buffered.length - 1);
|
|
143
|
+
this._adapter.setBufferedValue(bufferedEnd);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
handleEnded = () => {
|
|
148
|
+
this._adapter.setIsPlaying(false);
|
|
149
|
+
this._adapter.setShowControls(true);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
handleVolumeChange(value: number) {
|
|
153
|
+
const video = this._adapter.getVideo();
|
|
154
|
+
if (!video) return;
|
|
155
|
+
const volume = Math.floor(value > 0 ? value : 0);
|
|
156
|
+
video.volume = volume / 100;
|
|
157
|
+
this._adapter.setVolume(volume);
|
|
158
|
+
this._adapter.setMuted(volume === 0 ? true : false);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
handleVolumeSilent = () => {
|
|
162
|
+
const video = this._adapter.getVideo();
|
|
163
|
+
const { volume, muted } = this.getStates();
|
|
164
|
+
if (!video) return;
|
|
165
|
+
if (muted) {
|
|
166
|
+
video.volume = volume / 100;
|
|
167
|
+
this._adapter.setVolume(volume);
|
|
168
|
+
this._adapter.setMuted(false);
|
|
169
|
+
} else {
|
|
170
|
+
video.volume = 0;
|
|
171
|
+
this._adapter.setMuted(true);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
checkFullScreen() {
|
|
176
|
+
const videoWrapper = this._adapter.getVideoWrapper();
|
|
177
|
+
if (!videoWrapper) return false;
|
|
178
|
+
return !!(
|
|
179
|
+
document.fullscreenElement === videoWrapper ||
|
|
180
|
+
// @ts-ignore
|
|
181
|
+
document?.webkitFullscreenElement === videoWrapper ||
|
|
182
|
+
// @ts-ignore
|
|
183
|
+
document?.mozFullScreenElement === videoWrapper ||
|
|
184
|
+
// @ts-ignore
|
|
185
|
+
document?.msFullscreenElement === videoWrapper ||
|
|
186
|
+
// @ts-ignore
|
|
187
|
+
videoWrapper?.webkitDisplayingFullscreen // iOS Safari 特殊处理
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
handleFullscreen = () => {
|
|
192
|
+
const videoWrapper = this._adapter.getVideoWrapper();
|
|
193
|
+
const isFullScreen = this.checkFullScreen();
|
|
194
|
+
if (videoWrapper) {
|
|
195
|
+
if (isFullScreen) {
|
|
196
|
+
document.exitFullscreen();
|
|
197
|
+
} else {
|
|
198
|
+
// record scroll position before entering fullscreen
|
|
199
|
+
this.scrollPosition = {
|
|
200
|
+
x: window.scrollX,
|
|
201
|
+
y: window.scrollY
|
|
202
|
+
};
|
|
203
|
+
videoWrapper.requestFullscreen();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
handleRateChange(rate: { label: string; value: number }, locale: any) {
|
|
209
|
+
const video = this._adapter.getVideo();
|
|
210
|
+
if (!video) return;
|
|
211
|
+
video.playbackRate = rate.value;
|
|
212
|
+
this._adapter.setPlaybackRate(rate.value);
|
|
213
|
+
this._adapter.notifyRateChange(rate.value);
|
|
214
|
+
this.handleTemporaryNotification(locale.rateChange.replace('${rate}', rate.label));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
handleQualityChange(quality: { label: string; value: string }, locale: any) {
|
|
218
|
+
this._adapter.setQuality(quality.value);
|
|
219
|
+
this._adapter.notifyQualityChange(quality.value);
|
|
220
|
+
this.handleTemporaryNotification(locale.qualityChange.replace('${quality}', quality.label));
|
|
221
|
+
this.restorePlayPosition();
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
handleRouteChange(route: { label: string; value: string }, locale: any) {
|
|
225
|
+
this._adapter.setRoute(route.value);
|
|
226
|
+
this._adapter.notifyRouteChange?.(route.value);
|
|
227
|
+
this.handleTemporaryNotification(locale.routeChange.replace('${route}', route.label));
|
|
228
|
+
this.restorePlayPosition();
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
handleMirror = (locale: any) => {
|
|
232
|
+
const { isMirror } = this.getStates();
|
|
233
|
+
this._adapter.setIsMirror(!isMirror);
|
|
234
|
+
this.handleTemporaryNotification(!isMirror ? locale.mirror : locale.cancelMirror);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
handlePictureInPicture = () => {
|
|
238
|
+
const video = this._adapter.getVideo();
|
|
239
|
+
if (!video) return;
|
|
240
|
+
video.requestPictureInPicture();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
handleLeavePictureInPicture = () => {
|
|
244
|
+
const video = this._adapter.getVideo();
|
|
245
|
+
if (!video) return;
|
|
246
|
+
this._adapter.setIsPlaying(!video.paused);
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
handleTemporaryNotification = (content: string) => {
|
|
250
|
+
this._adapter.setNotificationContent(content);
|
|
251
|
+
this._adapter.setShowNotification(true);
|
|
252
|
+
setTimeout(() => {
|
|
253
|
+
this._adapter.setShowNotification(false);
|
|
254
|
+
}, 1000);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
restorePlayPosition() {
|
|
258
|
+
const video = this._adapter.getVideo();
|
|
259
|
+
if (!video) return;
|
|
260
|
+
const wasPlaying = !video.paused;
|
|
261
|
+
const currentTime = video.currentTime;
|
|
262
|
+
|
|
263
|
+
const handleLoaded = () => {
|
|
264
|
+
video.currentTime = currentTime;
|
|
265
|
+
if (wasPlaying) {
|
|
266
|
+
video.play();
|
|
267
|
+
}
|
|
268
|
+
video.removeEventListener('loadeddata', handleLoaded);
|
|
269
|
+
};
|
|
270
|
+
video.addEventListener('loadeddata', handleLoaded);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
handleMouseEnterWrapper = () => {
|
|
274
|
+
this._adapter.setShowControls(true);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
handleMouseLeaveWrapper = () => {
|
|
278
|
+
const { isPlaying } = this.getStates();
|
|
279
|
+
if (isPlaying) {
|
|
280
|
+
this._adapter.setShowControls(false);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
handleFullscreenChange = () => {
|
|
285
|
+
const isFullScreen = this.checkFullScreen();
|
|
286
|
+
if (isFullScreen) {
|
|
287
|
+
document.addEventListener('mousemove', this.handleMouseMove);
|
|
288
|
+
} else {
|
|
289
|
+
// according to the exit fullScreen has two way, Esc && click the button
|
|
290
|
+
// so we need to restore scroll position after exiting fullscreen
|
|
291
|
+
if (this.scrollPosition) {
|
|
292
|
+
setTimeout(() => {
|
|
293
|
+
window.scrollTo(this.scrollPosition.x, this.scrollPosition.y);
|
|
294
|
+
this.scrollPosition = null;
|
|
295
|
+
}, 0);
|
|
296
|
+
}
|
|
297
|
+
document.removeEventListener('mousemove', this.handleMouseMove);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
registerEvent = () => {
|
|
302
|
+
const video = this._adapter.getVideo();
|
|
303
|
+
if (!video) return;
|
|
304
|
+
document.addEventListener('keydown', (e) => this.handleBodyKeyDown(e));
|
|
305
|
+
document.addEventListener('fullscreenchange', this.handleFullscreenChange);
|
|
306
|
+
video.addEventListener('leavepictureinpicture', this.handleLeavePictureInPicture);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
unregisterEvent = () => {
|
|
310
|
+
const video = this._adapter.getVideo();
|
|
311
|
+
if (!video) return;
|
|
312
|
+
document.removeEventListener('keydown', (e) => this.handleBodyKeyDown(e));
|
|
313
|
+
document.removeEventListener('fullscreenchange', this.handleFullscreenChange);
|
|
314
|
+
video.removeEventListener('leavepictureinpicture', this.handleLeavePictureInPicture);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
handleBodyKeyDown(e: KeyboardEvent) {
|
|
318
|
+
const { currentTime, volume } = this.getStates();
|
|
319
|
+
const { seekTime } = this.getProps();
|
|
320
|
+
if (e.key === ' ') {
|
|
321
|
+
this.handlePlayOrPause();
|
|
322
|
+
// } else if (e.key === 'ArrowUp') {
|
|
323
|
+
// this.handleVolumeChange(volume + numbers.DEFAULT_VOLUME_STEP);
|
|
324
|
+
// } else if (e.key === 'ArrowDown') {
|
|
325
|
+
// this.handleVolumeChange(volume - numbers.DEFAULT_VOLUME_STEP);
|
|
326
|
+
} else if (e.key === 'ArrowLeft') {
|
|
327
|
+
this.handleTimeChange(currentTime - seekTime);
|
|
328
|
+
} else if (e.key === 'ArrowRight') {
|
|
329
|
+
this.handleTimeChange(currentTime + seekTime);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import BaseFoundation, { DefaultAdapter } from '../base/foundation';
|
|
2
|
+
|
|
3
|
+
export interface MarkerListItem {
|
|
4
|
+
start: number;
|
|
5
|
+
end: number;
|
|
6
|
+
title: string;
|
|
7
|
+
width: string;
|
|
8
|
+
left: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface Marker {
|
|
12
|
+
start: number;
|
|
13
|
+
title: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface VideoProgressAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
|
|
17
|
+
getSliderRef: () => HTMLDivElement | null;
|
|
18
|
+
getMarkersList: () => MarkerListItem[];
|
|
19
|
+
setIsDragging: (isDragging: boolean) => void;
|
|
20
|
+
setIsHandleHovering: (isHandleHovering: boolean) => void;
|
|
21
|
+
setActiveIndex: (activeIndex: number) => void;
|
|
22
|
+
setMovingInfo: (movingInfo: { progress: number; offset: number; value: number } | null) => void
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default class VideoProgressFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<VideoProgressAdapter<P, S>, P, S> {
|
|
26
|
+
constructor(adapter: VideoProgressAdapter<P, S>) {
|
|
27
|
+
super({ ...adapter });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
handleDocumentMouseMove = (e: MouseEvent) => {
|
|
31
|
+
const { isDragging } = this.getStates();
|
|
32
|
+
if (isDragging) {
|
|
33
|
+
this.handleMouseEvent(e, true);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
handleDocumentMouseUp = () => {
|
|
38
|
+
const { isDragging } = this.getStates();
|
|
39
|
+
if (isDragging) {
|
|
40
|
+
this._adapter.setIsDragging(false);
|
|
41
|
+
}
|
|
42
|
+
document.removeEventListener('mousemove', this.handleDocumentMouseMove);
|
|
43
|
+
document.removeEventListener('mouseup', this.handleDocumentMouseUp);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
handleMouseDown = (e: any) => {
|
|
47
|
+
this._adapter.setIsDragging(true);
|
|
48
|
+
this.handleMouseEvent(e, true);
|
|
49
|
+
document.addEventListener('mousemove', this.handleDocumentMouseMove);
|
|
50
|
+
document.addEventListener('mouseup', this.handleDocumentMouseUp);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
handleMouseUp = () => {
|
|
54
|
+
const { isDragging } = this.getStates();
|
|
55
|
+
if (isDragging) {
|
|
56
|
+
this._adapter.setIsDragging(false);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
handleMouseEvent = (e: any, shouldSetValue: boolean = true) => {
|
|
61
|
+
const { isDragging } = this.getStates();
|
|
62
|
+
const { onChange, max } = this.getProps();
|
|
63
|
+
const sliderRef = this._adapter.getSliderRef();
|
|
64
|
+
if (!sliderRef) return;
|
|
65
|
+
const rect = sliderRef.getBoundingClientRect();
|
|
66
|
+
const offset = (e.clientX - rect.left);
|
|
67
|
+
const total = rect.width;
|
|
68
|
+
const percentage = Math.min(Math.max(offset / total, 0), 1);
|
|
69
|
+
const value = percentage * max;
|
|
70
|
+
|
|
71
|
+
if (shouldSetValue && (isDragging || e.type === 'mousedown')) {
|
|
72
|
+
this.setActiveIndex(value);
|
|
73
|
+
onChange(value);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
this._adapter.setMovingInfo({
|
|
77
|
+
progress: percentage,
|
|
78
|
+
offset: offset - rect.width / 2,
|
|
79
|
+
value
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
handleSliderMouseEnter = (index: number) => {
|
|
84
|
+
const { value: currentValue } = this.getProps();
|
|
85
|
+
const markersList = this._adapter.getMarkersList();
|
|
86
|
+
const currentSlider = markersList[index];
|
|
87
|
+
if (currentSlider.start < currentValue && currentSlider.end > currentValue) {
|
|
88
|
+
this._adapter.setIsHandleHovering(true);
|
|
89
|
+
} else {
|
|
90
|
+
this._adapter.setIsHandleHovering(false);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
handleSliderMouseLeave = (index: number) => {
|
|
95
|
+
const { value: currentValue } = this.getProps();
|
|
96
|
+
const markersList = this._adapter.getMarkersList();
|
|
97
|
+
const currentSlider = markersList[index];
|
|
98
|
+
if (currentSlider.start < currentValue && currentSlider.end > currentValue) {
|
|
99
|
+
this._adapter.setIsHandleHovering(false);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
setActiveIndex = (currentValue: number) => {
|
|
104
|
+
const markersList = this._adapter.getMarkersList();
|
|
105
|
+
markersList.map((marker: MarkerListItem, index: number) => {
|
|
106
|
+
if (currentValue < marker.end && currentValue > marker.start) {
|
|
107
|
+
this._adapter.setIsHandleHovering(true);
|
|
108
|
+
this._adapter.setActiveIndex(index);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
getValueWidth = (marker: MarkerListItem, value: number) => {
|
|
114
|
+
const { start, end } = marker;
|
|
115
|
+
if (value > end) {
|
|
116
|
+
return 'calc(100% - 2px)';
|
|
117
|
+
} else if (value < start) {
|
|
118
|
+
return '0%';
|
|
119
|
+
} else {
|
|
120
|
+
return `${(value - start) / (end - start) * 100}%`;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Get the width of the video being played
|
|
125
|
+
getPlayedWidth = (marker: MarkerListItem) => {
|
|
126
|
+
const { value: currentValue } = this.getProps();
|
|
127
|
+
return this.getValueWidth(marker, currentValue);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
getLoadedWidth = (marker: MarkerListItem) => {
|
|
131
|
+
const { bufferedValue } = this.getProps();
|
|
132
|
+
return this.getValueWidth(marker, bufferedValue);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// Color
|
|
2
|
+
$color-videoPlayer_theme_dark-text: var(--semi-color-bg-0); // dark theme 字体色
|
|
3
|
+
$color-videoPlayer_theme_dark-bg: rgba(var(--semi-grey-8), 1); // dark theme 背景色
|
|
4
|
+
$color-videoPlayer_theme_light-text: rgba(var(--semi-grey-8), 1); // light theme 字体色
|
|
5
|
+
$color-videoPlayer_theme_light-bg: var(--semi-color-disabled-bg); // light theme 背景色
|
|
6
|
+
$color-videoPlayer_pause-bg: var(--semi-color-text-1); // 暂停按钮颜色
|
|
7
|
+
$color-videoPlayer_notification-bg: var(--semi-color-overlay-bg); // notification 背景色
|
|
8
|
+
$color-videoPlayer_notification-text: var(--semi-color-default); // notification 字体色
|
|
9
|
+
$color-videoPlayer_controls-bg: rgba(28, 31, 35, 0.8); // 控制栏背景色
|
|
10
|
+
$color-videoPlayer_controls_item-bg: var(--semi-color-overlay-bg); // 控制栏 item 背景色
|
|
11
|
+
$color-videoPlayer_controls-text: #fff; // 控制栏文字色
|
|
12
|
+
$color-videoPlayer_controls_item_popup-bg-default: var(--semi-color-overlay-bg); // 控制栏弹层背景色
|
|
13
|
+
$color-videoPlayer_controls_item_popup-bg-hover: rgba(67, 68, 74, 1); // 控制栏弹层背景色 - hover
|
|
14
|
+
$color-videoPlayer_controls_popup_item-text-default: rgba(#fff, 0.7); // 控制栏文字色
|
|
15
|
+
$color-videoPlayer_controls_popup_item-text-active: var(--semi-color-primary); // 控制栏弹层文字色 - 选中
|
|
16
|
+
$color-videoPlayer_progress_bar-bg-played: var(--semi-color-primary); // 进度条已播放部分背景色
|
|
17
|
+
$color-videoPlayer_progress_bar-bg-loaded: rgba(var(--semi-grey-3), 1); // 进度条已加载部分背景色
|
|
18
|
+
$color-videoPlayer_progress_bar-bg-unplayed: rgba(var(--semi-grey-5), 1); // 进度条未播放部分背景色
|
|
19
|
+
$color-videoPlayer_progress_bar_handle-bg: #fff; // handle 背景色
|
|
20
|
+
$color-videoPlayer_progress_bar_handle-border: var(--semi-color-primary); // handle 边框色
|
|
21
|
+
$color-videoPlayer_progress_bar_handle-shadow: var(--semi-color-shadow); // handle 阴影色
|
|
22
|
+
|
|
23
|
+
// Width/Height
|
|
24
|
+
$height-videoPlayer_progress_bar_hotSpot-default: 20px; // 进度条热区 default 高度
|
|
25
|
+
$height-videoPlayer_progress_bar-default: 4px; // 进度条 default 高度
|
|
26
|
+
$height-videoPlayer_progress_bar-hover: 10px; // 进度条 hover 高度
|
|
27
|
+
$height-videoPlayer_progress_bar_handle: 16px; // 进度条 handle 高度
|
|
28
|
+
$height-videoPlayer_controls_menu-default: 56px; // 控制栏 default 高度
|
|
29
|
+
$height-videoPlayer_controls_volume-default: 160px; // 控制栏音量 default 高度
|
|
30
|
+
$height-videoPlayer_controls_popup-default: 24px; // 控制栏弹层类元素 default 高度
|
|
31
|
+
$height-videoPlayer_controls_popup_item-default: 32px; // 控制栏弹层类元素 item default 高度
|
|
32
|
+
$width-videoPlayer_controls_volume-default: 40px; // 控制栏音量 default 宽度
|
|
33
|
+
$width-videoPlayer_controls_popup_item-default: 50px; // 控制栏弹层类元素 default 宽度
|
|
34
|
+
$width-videoPlayer_controls_popup-default: 48px; // 控制栏弹层 default 宽度
|
|
35
|
+
|
|
36
|
+
// Spacing
|
|
37
|
+
$spacing-videoPlayer-progress_bar_chapter-marginRight: 2px; // 进度条分节间距
|
|
38
|
+
$spacing-videoPlayer_notification-bottom: 22px; // notification 距离菜单栏距离
|
|
39
|
+
$spacing-videoPlayer_notification-left: 8px; // notification 距离菜单栏左侧距离
|
|
40
|
+
$spacing-videoPlayer_notification_text-paddingY: 8px; // notification 文字垂直方向 padding
|
|
41
|
+
$spacing-videoPlayer_notification_text-paddingX: 12px; // notification 文字水平方向 padding
|
|
42
|
+
$spacing-videoPlayer-controls-padding: $spacing-base-tight $spacing-base; // 控制栏 padding
|
|
43
|
+
$spacing-videoPlayer-controls_item-gap: $spacing-tight; // 控制栏 item 间距
|
|
44
|
+
$spacing-videoPlayer-controls_time-paddingX: 8px; // 控制栏时间 paddingX
|
|
45
|
+
$spacing-videoPlayer-controls_volume_title-paddingX: 10px; // 控制栏音量标题文字 paddingX
|
|
46
|
+
$spacing-videoPlayer-controls_volume_title-paddingY: 0px; // 控制栏音量标题文字 paddingX
|
|
47
|
+
$spacing-videoPlayer-controls_volume_popup-paddingY: 0px; // 控制栏音量弹层 paddingX
|
|
48
|
+
$spacing-videoPlayer-controls_volume_popup-paddingX: $spacing-extra-tight; // 控制栏音量弹层 paddingX
|
|
49
|
+
$spacing-videoPlayer-controls_popup-paddingX: $spacing-tight; // 控制栏弹层元素 paddingX
|
|
50
|
+
$spacing-videoPlayer-controls_popup-paddingY: 0px; // 控制栏弹层元素 paddingY
|
|
51
|
+
$spacing-videoPlayer-progress_bar_wrapper-marginX: $spacing-tight; // 进度条 wrapper marginX
|
|
52
|
+
$spacing-videoPlayer-progress_bar_wrapper-marginY: 0px; // 进度条 wrapper marginY
|
|
53
|
+
$spacing-videoPlayer-progress_bar_tooltip-top: 6px; // 进度条 Tooltip top 值
|
|
54
|
+
$spacing-videoPlayer_progress_bar_handle-top: 15px; // 进度条 handle top 值
|
|
55
|
+
$spacing-videoPlayer_error_svg-marginBottom: 12px; // error svg marginBottom
|
|
56
|
+
|
|
57
|
+
// Radius
|
|
58
|
+
$radius-videoPlayer_notification: 3px; // notification 圆角
|
|
59
|
+
$radius-videoPlayer_progress_bar_handle: 50%; // 进度条 handle 圆角
|
|
60
|
+
$radius-videoPlayer_progress_bar: 999px; // 进度条圆角
|
|
61
|
+
$radius-videoPlayer_controls_item: 3px; // 控制栏 item 圆角
|
|
62
|
+
$radius-videoPlayer_controls_popup: 4px; // 控制栏弹层圆角
|
|
63
|
+
|
|
64
|
+
// Font
|
|
65
|
+
$font-videoPlayer_notification-fontSize: $font-size-regular; // notification 字体大小
|
|
66
|
+
$font-videoPlayer_controls_item-fontSize: $font-size-small; // 控制栏 item 字体大小
|
|
67
|
+
$font-videoPlayer_controls_time_text-fontSize: $font-size-regular; // 控制栏时间字体大小
|
|
68
|
+
$font-videoPlayer_error-fontSize: $font-size-regular; // error 字体大小
|
|
69
|
+
$font-videoPlayer_notification-lineHeight: 20px; // notification 行高
|
|
70
|
+
$font-videoPlayer_controls_popup_item-lineHeight: 16px; // 控制栏 item 行高
|
|
71
|
+
$font-videoPlayer_controls_popup_item-fontWeight: 600; // 控制栏 item 字体粗细
|
|
72
|
+
$font-videoPlayer_error-fontWeight: 600; // error 字体粗细
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|