@maas/vue-equipment 0.1.2 → 0.2.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/dist/composables/index.d.mts +87 -0
- package/dist/composables/index.d.ts +87 -0
- package/dist/composables/index.js +284 -0
- package/dist/composables/index.js.map +1 -0
- package/dist/composables/index.mjs +254 -0
- package/dist/composables/index.mjs.map +1 -0
- package/dist/nuxt/module.cjs +5 -0
- package/dist/nuxt/module.d.ts +9 -0
- package/dist/nuxt/module.json +5 -0
- package/dist/nuxt/module.mjs +121 -0
- package/dist/nuxt/types.d.ts +15 -0
- package/dist/plugins/MagicModal/index.d.ts +4 -0
- package/dist/plugins/MagicModal/index.mjs +8 -0
- package/dist/plugins/MagicModal/nuxt.d.ts +2 -0
- package/dist/plugins/MagicModal/nuxt.mjs +5 -0
- package/dist/plugins/MagicModal/src/components/MagicModal.vue +254 -0
- package/dist/plugins/MagicModal/src/components/MagicModal.vue.d.ts +43 -0
- package/dist/plugins/MagicModal/src/composables/useModalApi.d.ts +18 -0
- package/dist/plugins/MagicModal/src/composables/useModalApi.mjs +74 -0
- package/dist/plugins/MagicModal/src/composables/useModalStore.d.ts +5 -0
- package/dist/plugins/MagicModal/src/composables/useModalStore.mjs +15 -0
- package/dist/plugins/MagicModal/src/store/modals.d.ts +4 -0
- package/dist/plugins/MagicModal/src/store/modals.mjs +9 -0
- package/dist/plugins/MagicModal/src/types/index.d.ts +15 -0
- package/dist/plugins/MagicModal/src/types/index.mjs +0 -0
- package/dist/plugins/MagicModal/src/utils/defaultOptions.d.ts +3 -0
- package/dist/plugins/MagicModal/src/utils/defaultOptions.mjs +15 -0
- package/dist/plugins/MagicPlayer/index.d.ts +7 -0
- package/dist/plugins/MagicPlayer/index.mjs +15 -0
- package/dist/plugins/MagicPlayer/nuxt.d.ts +2 -0
- package/dist/plugins/MagicPlayer/nuxt.mjs +5 -0
- package/dist/plugins/MagicPlayer/src/components/MagicPlayer.vue +103 -0
- package/dist/plugins/MagicPlayer/src/components/MagicPlayer.vue.d.ts +86 -0
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerControls.vue +262 -0
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerControls.vue.d.ts +25 -0
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerMuxPopover.vue +132 -0
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerMuxPopover.vue.d.ts +12 -0
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerTimeline.vue +155 -0
- package/dist/plugins/MagicPlayer/src/components/MagicPlayerTimeline.vue.d.ts +2 -0
- package/dist/plugins/MagicPlayer/src/components/icons/FullscreenEnter.vue +13 -0
- package/dist/plugins/MagicPlayer/src/components/icons/FullscreenEnter.vue.d.ts +2 -0
- package/dist/plugins/MagicPlayer/src/components/icons/FullscreenExit.vue +14 -0
- package/dist/plugins/MagicPlayer/src/components/icons/FullscreenExit.vue.d.ts +2 -0
- package/dist/plugins/MagicPlayer/src/components/icons/Pause.vue +14 -0
- package/dist/plugins/MagicPlayer/src/components/icons/Pause.vue.d.ts +2 -0
- package/dist/plugins/MagicPlayer/src/components/icons/Play.vue +11 -0
- package/dist/plugins/MagicPlayer/src/components/icons/Play.vue.d.ts +2 -0
- package/dist/plugins/MagicPlayer/src/components/icons/VolumeOff.vue +14 -0
- package/dist/plugins/MagicPlayer/src/components/icons/VolumeOff.vue.d.ts +2 -0
- package/dist/plugins/MagicPlayer/src/components/icons/VolumeOn.vue +11 -0
- package/dist/plugins/MagicPlayer/src/components/icons/VolumeOn.vue.d.ts +2 -0
- package/dist/plugins/MagicPlayer/src/components/icons/Waiting.vue +38 -0
- package/dist/plugins/MagicPlayer/src/components/icons/Waiting.vue.d.ts +2 -0
- package/dist/plugins/MagicPlayer/src/composables/useControls.d.ts +8 -0
- package/dist/plugins/MagicPlayer/src/composables/useControls.mjs +15 -0
- package/dist/plugins/MagicPlayer/src/composables/useControlsApi.d.ts +17 -0
- package/dist/plugins/MagicPlayer/src/composables/useControlsApi.mjs +129 -0
- package/dist/plugins/MagicPlayer/src/composables/useMediaApi.d.ts +15 -0
- package/dist/plugins/MagicPlayer/src/composables/useMediaApi.mjs +122 -0
- package/dist/plugins/MagicPlayer/src/composables/usePlayer.d.ts +12 -0
- package/dist/plugins/MagicPlayer/src/composables/usePlayer.mjs +33 -0
- package/dist/plugins/MagicPlayer/src/composables/usePlayerApi.d.ts +20 -0
- package/dist/plugins/MagicPlayer/src/composables/usePlayerApi.mjs +50 -0
- package/dist/plugins/MagicPlayer/src/composables/useRuntimeSourceProvider.d.ts +8 -0
- package/dist/plugins/MagicPlayer/src/composables/useRuntimeSourceProvider.mjs +49 -0
- package/dist/plugins/MagicPlayer/src/types/index.d.ts +15 -0
- package/dist/plugins/MagicPlayer/src/types/index.mjs +1 -0
- package/dist/plugins/MagicPlayer/src/types/injectionKeys.d.ts +45 -0
- package/dist/plugins/MagicPlayer/src/types/injectionKeys.mjs +10 -0
- package/dist/plugins/MagicPlayer/src/utils/index.d.ts +4 -0
- package/dist/plugins/MagicPlayer/src/utils/index.mjs +19 -0
- package/dist/plugins/MagicScroll/index.d.ts +7 -0
- package/dist/plugins/MagicScroll/index.mjs +19 -0
- package/dist/plugins/MagicScroll/nuxt.d.ts +2 -0
- package/dist/plugins/MagicScroll/nuxt.mjs +5 -0
- package/dist/plugins/MagicScroll/src/components/MagicScrollCollision.vue +35 -0
- package/dist/plugins/MagicScroll/src/components/MagicScrollCollision.vue.d.ts +20 -0
- package/dist/plugins/MagicScroll/src/components/MagicScrollProvider.vue +34 -0
- package/dist/plugins/MagicScroll/src/components/MagicScrollProvider.vue.d.ts +21 -0
- package/dist/plugins/MagicScroll/src/components/MagicScrollScene.vue +80 -0
- package/dist/plugins/MagicScroll/src/components/MagicScrollScene.vue.d.ts +41 -0
- package/dist/plugins/MagicScroll/src/components/MagicScrollTransform.vue +42 -0
- package/dist/plugins/MagicScroll/src/components/MagicScrollTransform.vue.d.ts +84 -0
- package/dist/plugins/MagicScroll/src/composables/useCollisionDetect.d.ts +6 -0
- package/dist/plugins/MagicScroll/src/composables/useCollisionDetect.mjs +116 -0
- package/dist/plugins/MagicScroll/src/composables/useEmitter.d.ts +15 -0
- package/dist/plugins/MagicScroll/src/composables/useEmitter.mjs +9 -0
- package/dist/plugins/MagicScroll/src/composables/useProgress.d.ts +7 -0
- package/dist/plugins/MagicScroll/src/composables/useProgress.mjs +59 -0
- package/dist/plugins/MagicScroll/src/store/index.d.ts +4 -0
- package/dist/plugins/MagicScroll/src/store/index.mjs +5 -0
- package/dist/plugins/MagicScroll/src/types/index.d.ts +34 -0
- package/dist/plugins/MagicScroll/src/types/index.mjs +1 -0
- package/dist/plugins/MagicScroll/src/types/injectionKeys.d.ts +12 -0
- package/dist/plugins/MagicScroll/src/types/injectionKeys.mjs +5 -0
- package/dist/plugins/MagicScroll/src/utils/index.d.ts +2 -0
- package/dist/plugins/MagicScroll/src/utils/index.mjs +6 -0
- package/dist/plugins/index.d.ts +3 -0
- package/dist/plugins/index.mjs +3 -0
- package/package.json +13 -16
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg
|
|
3
|
+
viewBox="0 0 24 24"
|
|
4
|
+
fill="currentColor"
|
|
5
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
6
|
+
>
|
|
7
|
+
<path
|
|
8
|
+
d="M16.4 4.2C17.0592 3.70557 18 4.17595 18 5V19C18 19.824 17.0592 20.2944 16.4 19.8L11.3333 16H7C6.44772 16 6 15.5523 6 15V9C6 8.44772 6.44772 8 7 8H11.3333L16.4 4.2Z"
|
|
9
|
+
/>
|
|
10
|
+
</svg>
|
|
11
|
+
</template>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg viewBox="0 0 48 48">
|
|
3
|
+
<circle
|
|
4
|
+
cx="24"
|
|
5
|
+
cy="24"
|
|
6
|
+
r="20"
|
|
7
|
+
fill="none"
|
|
8
|
+
stroke-width="4"
|
|
9
|
+
stroke-linecap="round"
|
|
10
|
+
></circle>
|
|
11
|
+
</svg>
|
|
12
|
+
</template>
|
|
13
|
+
|
|
14
|
+
<style scoped>
|
|
15
|
+
svg > circle {
|
|
16
|
+
fill: none;
|
|
17
|
+
transform-origin: center;
|
|
18
|
+
stroke-dasharray: 1, 200;
|
|
19
|
+
stroke-dashoffset: 0;
|
|
20
|
+
animation: spinner 2.5s ease-in-out infinite;
|
|
21
|
+
stroke: currentColor;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@keyframes spinner {
|
|
25
|
+
0% {
|
|
26
|
+
stroke-dasharray: 1, 200;
|
|
27
|
+
transform: rotate(0deg);
|
|
28
|
+
}
|
|
29
|
+
50% {
|
|
30
|
+
stroke-dasharray: 100, 200;
|
|
31
|
+
transform: rotate(360deg);
|
|
32
|
+
}
|
|
33
|
+
100% {
|
|
34
|
+
stroke-dasharray: 1, 200;
|
|
35
|
+
transform: rotate(720deg);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
</style>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type UseControlsApiReturn } from './useControlsApi.js';
|
|
2
|
+
import type { UseControlsArgs } from '../types.js';
|
|
3
|
+
type UseControlsReturn = {
|
|
4
|
+
controlsApi: UseControlsApiReturn;
|
|
5
|
+
};
|
|
6
|
+
export declare function useProvideControls(args: UseControlsArgs): UseControlsReturn;
|
|
7
|
+
export declare function useInjectControls(): UseControlsReturn;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { provide, inject } from "vue";
|
|
2
|
+
import { useControlsApi } from "./useControlsApi.mjs";
|
|
3
|
+
import { ControlsApiInjectionKey } from "./../types/index.mjs";
|
|
4
|
+
export function useProvideControls(args) {
|
|
5
|
+
const controlsApi = useControlsApi(args);
|
|
6
|
+
provide(ControlsApiInjectionKey, controlsApi);
|
|
7
|
+
return {
|
|
8
|
+
controlsApi
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export function useInjectControls() {
|
|
12
|
+
return {
|
|
13
|
+
controlsApi: inject(ControlsApiInjectionKey)
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { UseControlsArgs } from '../types.js';
|
|
2
|
+
export declare function useControlsApi(args: UseControlsArgs): {
|
|
3
|
+
entered: import("vue").Ref<boolean>;
|
|
4
|
+
dragging: import("vue").Ref<boolean>;
|
|
5
|
+
seekedTime: import("vue").Ref<number>;
|
|
6
|
+
seekedPercentage: import("vue").Ref<number>;
|
|
7
|
+
scrubbedPercentage: import("vue").Ref<number>;
|
|
8
|
+
bufferedPercentage: import("vue").ComputedRef<number>;
|
|
9
|
+
thumbPercentage: import("vue").Ref<number>;
|
|
10
|
+
popoverOffsetX: import("vue").Ref<number>;
|
|
11
|
+
onMouseEnter: () => void;
|
|
12
|
+
onMouseLeave: () => void;
|
|
13
|
+
onPointerDown: (e: MouseEvent | TouchEvent) => void;
|
|
14
|
+
onPointerUp: () => void;
|
|
15
|
+
onPointerMove: (e: MouseEvent | TouchEvent) => void;
|
|
16
|
+
};
|
|
17
|
+
export type UseControlsApiReturn = ReturnType<typeof useControlsApi>;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { ref, computed, watch } from "vue";
|
|
2
|
+
import { toValue } from "@vueuse/shared";
|
|
3
|
+
import {
|
|
4
|
+
useResizeObserver,
|
|
5
|
+
useEventListener,
|
|
6
|
+
defaultWindow
|
|
7
|
+
} from "@vueuse/core";
|
|
8
|
+
import { clampValue, mapValue } from "./../utils/index.mjs";
|
|
9
|
+
import { useInjectPlayer } from "./usePlayer.mjs";
|
|
10
|
+
export function useControlsApi(args) {
|
|
11
|
+
const { mediaApi, playerApi } = useInjectPlayer();
|
|
12
|
+
const { playing, buffered, duration, currentTime } = mediaApi;
|
|
13
|
+
const { play, pause, seek } = playerApi;
|
|
14
|
+
const entered = ref(false);
|
|
15
|
+
const dragging = ref(false);
|
|
16
|
+
const seekedTime = ref(0);
|
|
17
|
+
const seekedPercentage = ref(0);
|
|
18
|
+
const scrubbedPercentage = ref(0);
|
|
19
|
+
const thumbPercentage = ref(0);
|
|
20
|
+
const popoverOffsetX = ref(0);
|
|
21
|
+
const bufferedPercentage = computed(() => {
|
|
22
|
+
const endBuffer = buffered.value.length > 0 ? buffered.value[0][1] : 0;
|
|
23
|
+
const percentage = endBuffer / duration.value * 100;
|
|
24
|
+
return clampValue(percentage, 0, thumbPercentage.value);
|
|
25
|
+
});
|
|
26
|
+
const resumePlay = ref(false);
|
|
27
|
+
const barRect = ref(void 0);
|
|
28
|
+
const trackRect = ref(void 0);
|
|
29
|
+
const popoverRect = ref(void 0);
|
|
30
|
+
function getPopoverOffsetX() {
|
|
31
|
+
if (!trackRect.value || !popoverRect.value || !barRect.value) {
|
|
32
|
+
return 0;
|
|
33
|
+
} else {
|
|
34
|
+
const trackFactor = barRect.value.width / trackRect.value.width;
|
|
35
|
+
const offsetXPercentage = Math.abs(trackRect.value.x - barRect.value.x) / barRect.value.width * 100;
|
|
36
|
+
const popoverWidthPercentage = popoverRect.value.width / barRect.value.width * 100;
|
|
37
|
+
const maxPercentage = 100 - popoverWidthPercentage;
|
|
38
|
+
const percentage = seekedPercentage.value / trackFactor + offsetXPercentage - popoverWidthPercentage / 2;
|
|
39
|
+
popoverOffsetX.value = clampValue(percentage, 0, maxPercentage);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function getTimelineTrackSize() {
|
|
43
|
+
trackRect.value = toValue(args.trackRef)?.getBoundingClientRect();
|
|
44
|
+
thumbPercentage.value = 100 - trackRect.value.height / trackRect.value.width * 100;
|
|
45
|
+
}
|
|
46
|
+
function getPopoverSizes() {
|
|
47
|
+
barRect.value = toValue(args.barRef)?.getBoundingClientRect();
|
|
48
|
+
popoverRect.value = toValue(args.popoverRef)?.getBoundingClientRect();
|
|
49
|
+
}
|
|
50
|
+
function seekToTrackPosition(absX) {
|
|
51
|
+
if (!trackRect.value) {
|
|
52
|
+
throw new Error("trackRect is undefined");
|
|
53
|
+
}
|
|
54
|
+
const relX = absX - trackRect.value.x - trackRect.value.height / 2;
|
|
55
|
+
const percentage = Math.round(relX / trackRect.value.width * 100);
|
|
56
|
+
seekedPercentage.value = clampValue(percentage, 0, thumbPercentage.value);
|
|
57
|
+
seekedTime.value = duration.value * mapValue(seekedPercentage.value, 0, thumbPercentage.value, 0, 100) / 100;
|
|
58
|
+
if (dragging.value) {
|
|
59
|
+
scrubbedPercentage.value = seekedPercentage.value;
|
|
60
|
+
seek(seekedTime.value);
|
|
61
|
+
}
|
|
62
|
+
getPopoverOffsetX();
|
|
63
|
+
}
|
|
64
|
+
function onMouseEnter() {
|
|
65
|
+
getTimelineTrackSize();
|
|
66
|
+
getPopoverSizes();
|
|
67
|
+
entered.value = true;
|
|
68
|
+
}
|
|
69
|
+
function onMouseLeave() {
|
|
70
|
+
entered.value = false;
|
|
71
|
+
dragging.value = false;
|
|
72
|
+
seekedTime.value = 0;
|
|
73
|
+
}
|
|
74
|
+
function onPointerDown(e) {
|
|
75
|
+
dragging.value = true;
|
|
76
|
+
resumePlay.value = playing.value;
|
|
77
|
+
pause();
|
|
78
|
+
const x = e instanceof MouseEvent ? e.pageX : e.touches[0].pageX;
|
|
79
|
+
seekToTrackPosition(x);
|
|
80
|
+
}
|
|
81
|
+
function onPointerUp() {
|
|
82
|
+
dragging.value = false;
|
|
83
|
+
if (resumePlay.value) {
|
|
84
|
+
play();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function onPointerMove(e) {
|
|
88
|
+
const x = e instanceof MouseEvent ? e.pageX : e.touches[0].pageX;
|
|
89
|
+
seekToTrackPosition(x);
|
|
90
|
+
}
|
|
91
|
+
watch(currentTime, (value) => {
|
|
92
|
+
const percentage = value / duration.value * 100;
|
|
93
|
+
scrubbedPercentage.value = mapValue(
|
|
94
|
+
percentage,
|
|
95
|
+
0,
|
|
96
|
+
100,
|
|
97
|
+
0,
|
|
98
|
+
thumbPercentage.value
|
|
99
|
+
);
|
|
100
|
+
});
|
|
101
|
+
useResizeObserver(args.trackRef, getTimelineTrackSize);
|
|
102
|
+
useResizeObserver(args.popoverRef, getPopoverSizes);
|
|
103
|
+
useEventListener(
|
|
104
|
+
defaultWindow,
|
|
105
|
+
"resize",
|
|
106
|
+
() => {
|
|
107
|
+
getTimelineTrackSize;
|
|
108
|
+
getPopoverSizes;
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
passive: true
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
return {
|
|
115
|
+
entered,
|
|
116
|
+
dragging,
|
|
117
|
+
seekedTime,
|
|
118
|
+
seekedPercentage,
|
|
119
|
+
scrubbedPercentage,
|
|
120
|
+
bufferedPercentage,
|
|
121
|
+
thumbPercentage,
|
|
122
|
+
popoverOffsetX,
|
|
123
|
+
onMouseEnter,
|
|
124
|
+
onMouseLeave,
|
|
125
|
+
onPointerDown,
|
|
126
|
+
onPointerUp,
|
|
127
|
+
onPointerMove
|
|
128
|
+
};
|
|
129
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { MaybeRef } from '@vueuse/shared';
|
|
2
|
+
export declare function useMediaApi(target: MaybeRef<HTMLMediaElement | null | undefined>): {
|
|
3
|
+
currentTime: import("vue").Ref<number>;
|
|
4
|
+
duration: import("vue").Ref<number>;
|
|
5
|
+
waiting: import("vue").Ref<boolean>;
|
|
6
|
+
seeking: import("vue").Ref<boolean>;
|
|
7
|
+
ended: import("vue").Ref<boolean>;
|
|
8
|
+
stalled: import("vue").Ref<boolean>;
|
|
9
|
+
buffered: import("vue").Ref<[number, number][]>;
|
|
10
|
+
playing: import("vue").Ref<boolean>;
|
|
11
|
+
rate: import("vue").Ref<number>;
|
|
12
|
+
volume: import("vue").Ref<number>;
|
|
13
|
+
muted: import("vue").Ref<boolean>;
|
|
14
|
+
};
|
|
15
|
+
export type UseMediaApiReturn = ReturnType<typeof useMediaApi>;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { ref, watch, unref } from "vue";
|
|
2
|
+
import { toValue, watchIgnorable } from "@vueuse/shared";
|
|
3
|
+
import { useEventListener } from "@vueuse/core";
|
|
4
|
+
export function useMediaApi(target) {
|
|
5
|
+
const currentTime = ref(0);
|
|
6
|
+
const duration = ref(0);
|
|
7
|
+
const seeking = ref(false);
|
|
8
|
+
const volume = ref(1);
|
|
9
|
+
const rate = ref(1);
|
|
10
|
+
const waiting = ref(false);
|
|
11
|
+
const ended = ref(false);
|
|
12
|
+
const playing = ref(false);
|
|
13
|
+
const stalled = ref(false);
|
|
14
|
+
const buffered = ref([]);
|
|
15
|
+
const muted = ref(false);
|
|
16
|
+
function timeRangeToArray(timeRanges) {
|
|
17
|
+
let ranges = [];
|
|
18
|
+
for (let i = 0; i < timeRanges.length; ++i)
|
|
19
|
+
ranges = [...ranges, [timeRanges.start(i), timeRanges.end(i)]];
|
|
20
|
+
return ranges;
|
|
21
|
+
}
|
|
22
|
+
watch([target, volume], () => {
|
|
23
|
+
const el = toValue(target);
|
|
24
|
+
if (!el)
|
|
25
|
+
return;
|
|
26
|
+
el.volume = volume.value;
|
|
27
|
+
});
|
|
28
|
+
watch([target, muted], () => {
|
|
29
|
+
const el = toValue(target);
|
|
30
|
+
if (!el)
|
|
31
|
+
return;
|
|
32
|
+
el.muted = muted.value;
|
|
33
|
+
});
|
|
34
|
+
watch([target, rate], () => {
|
|
35
|
+
const el = toValue(target);
|
|
36
|
+
if (!el)
|
|
37
|
+
return;
|
|
38
|
+
el.playbackRate = rate.value;
|
|
39
|
+
});
|
|
40
|
+
const { ignoreUpdates: ignoreCurrentTimeUpdates } = watchIgnorable(
|
|
41
|
+
currentTime,
|
|
42
|
+
(time) => {
|
|
43
|
+
const el = toValue(target);
|
|
44
|
+
if (!el)
|
|
45
|
+
return;
|
|
46
|
+
el.currentTime = unref(time);
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
const { ignoreUpdates: ignorePlayingUpdates } = watchIgnorable(
|
|
50
|
+
playing,
|
|
51
|
+
(isPlaying) => {
|
|
52
|
+
const el = toValue(target);
|
|
53
|
+
if (!el)
|
|
54
|
+
return;
|
|
55
|
+
isPlaying ? el.play() : el.pause();
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
useEventListener(target, "timeupdate", () => {
|
|
59
|
+
ignoreCurrentTimeUpdates(
|
|
60
|
+
() => currentTime.value = toValue(target).currentTime
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
useEventListener(target, "durationchange", () => {
|
|
64
|
+
duration.value = toValue(target).duration;
|
|
65
|
+
});
|
|
66
|
+
useEventListener(target, "progress", () => {
|
|
67
|
+
buffered.value = timeRangeToArray(toValue(target).buffered);
|
|
68
|
+
});
|
|
69
|
+
useEventListener(target, "seeking", () => {
|
|
70
|
+
seeking.value = true;
|
|
71
|
+
});
|
|
72
|
+
useEventListener(target, "seeked", () => {
|
|
73
|
+
seeking.value = false;
|
|
74
|
+
});
|
|
75
|
+
useEventListener(target, ["waiting", "loadstart"], () => {
|
|
76
|
+
waiting.value = true;
|
|
77
|
+
ignorePlayingUpdates(() => playing.value = false);
|
|
78
|
+
});
|
|
79
|
+
useEventListener(target, "loadeddata", () => {
|
|
80
|
+
waiting.value = false;
|
|
81
|
+
});
|
|
82
|
+
useEventListener(target, "playing", () => {
|
|
83
|
+
waiting.value = false;
|
|
84
|
+
ended.value = false;
|
|
85
|
+
ignorePlayingUpdates(() => playing.value = true);
|
|
86
|
+
});
|
|
87
|
+
useEventListener(target, "ratechange", () => {
|
|
88
|
+
rate.value = toValue(target).playbackRate;
|
|
89
|
+
});
|
|
90
|
+
useEventListener(target, "stalled", () => {
|
|
91
|
+
stalled.value = true;
|
|
92
|
+
});
|
|
93
|
+
useEventListener(target, "ended", () => {
|
|
94
|
+
ended.value = true;
|
|
95
|
+
});
|
|
96
|
+
useEventListener(target, "pause", () => {
|
|
97
|
+
playing.value = false;
|
|
98
|
+
});
|
|
99
|
+
useEventListener(target, "play", () => {
|
|
100
|
+
playing.value = true;
|
|
101
|
+
});
|
|
102
|
+
useEventListener(target, "volumechange", () => {
|
|
103
|
+
const el = toValue(target);
|
|
104
|
+
if (!el)
|
|
105
|
+
return;
|
|
106
|
+
volume.value = el.volume;
|
|
107
|
+
muted.value = el.muted;
|
|
108
|
+
});
|
|
109
|
+
return {
|
|
110
|
+
currentTime,
|
|
111
|
+
duration,
|
|
112
|
+
waiting,
|
|
113
|
+
seeking,
|
|
114
|
+
ended,
|
|
115
|
+
stalled,
|
|
116
|
+
buffered,
|
|
117
|
+
playing,
|
|
118
|
+
rate,
|
|
119
|
+
volume,
|
|
120
|
+
muted
|
|
121
|
+
};
|
|
122
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type UseMediaApiReturn } from './useMediaApi.js';
|
|
2
|
+
import { type UsePlayerApiReturn } from './usePlayerApi.js';
|
|
3
|
+
import { type UseRuntimeSourceProviderReturn } from './useRuntimeSourceProvider.js';
|
|
4
|
+
import { type UsePlayerArgs } from './../types.js';
|
|
5
|
+
type UsePlayerReturn = {
|
|
6
|
+
playerApi: UsePlayerApiReturn;
|
|
7
|
+
mediaApi: UseMediaApiReturn;
|
|
8
|
+
runtimeProvider: UseRuntimeSourceProviderReturn;
|
|
9
|
+
};
|
|
10
|
+
export declare function useProvidePlayer(args: UsePlayerArgs): UsePlayerReturn;
|
|
11
|
+
export declare function useInjectPlayer(): UsePlayerReturn;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { provide, inject } from "vue";
|
|
2
|
+
import { useMediaApi } from "./useMediaApi.mjs";
|
|
3
|
+
import { usePlayerApi } from "./usePlayerApi.mjs";
|
|
4
|
+
import {
|
|
5
|
+
useRuntimeSourceProvider
|
|
6
|
+
} from "./useRuntimeSourceProvider.mjs";
|
|
7
|
+
import {
|
|
8
|
+
MediaApiInjectionKey,
|
|
9
|
+
PlayerApiInjectionKey,
|
|
10
|
+
RuntimeSourceProviderInjectionKey
|
|
11
|
+
} from "./../types/index.mjs";
|
|
12
|
+
export function useProvidePlayer(args) {
|
|
13
|
+
const mediaApi = useMediaApi(args.videoRef);
|
|
14
|
+
provide(MediaApiInjectionKey, mediaApi);
|
|
15
|
+
const playerApi = usePlayerApi({ ...args, mediaApi });
|
|
16
|
+
provide(PlayerApiInjectionKey, playerApi);
|
|
17
|
+
const runtimeProvider = useRuntimeSourceProvider(args);
|
|
18
|
+
provide(RuntimeSourceProviderInjectionKey, runtimeProvider);
|
|
19
|
+
return {
|
|
20
|
+
playerApi,
|
|
21
|
+
mediaApi,
|
|
22
|
+
runtimeProvider
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function useInjectPlayer() {
|
|
26
|
+
return {
|
|
27
|
+
playerApi: inject(PlayerApiInjectionKey),
|
|
28
|
+
mediaApi: inject(MediaApiInjectionKey),
|
|
29
|
+
runtimeProvider: inject(
|
|
30
|
+
RuntimeSourceProviderInjectionKey
|
|
31
|
+
)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { UseMediaApiReturn } from './useMediaApi.js';
|
|
2
|
+
import type { UsePlayerArgs } from '../types.js';
|
|
3
|
+
type UsePlayerApiArgs = Pick<UsePlayerArgs, 'playerRef' | 'videoRef'> & {
|
|
4
|
+
mediaApi: UseMediaApiReturn;
|
|
5
|
+
};
|
|
6
|
+
export declare function usePlayerApi(args: UsePlayerApiArgs): {
|
|
7
|
+
isFullscreen: import("vue").Ref<boolean>;
|
|
8
|
+
touched: import("vue").Ref<boolean>;
|
|
9
|
+
play: () => void;
|
|
10
|
+
pause: () => void;
|
|
11
|
+
togglePlay: () => void;
|
|
12
|
+
seek: (time: number) => void;
|
|
13
|
+
mute: () => void;
|
|
14
|
+
unmute: () => void;
|
|
15
|
+
enterFullscreen: () => Promise<void>;
|
|
16
|
+
exitFullscreen: () => Promise<void>;
|
|
17
|
+
toggleFullscreen: () => Promise<void>;
|
|
18
|
+
};
|
|
19
|
+
export type UsePlayerApiReturn = ReturnType<typeof usePlayerApi>;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ref, watch } from "vue";
|
|
2
|
+
import { useFullscreen } from "@vueuse/core";
|
|
3
|
+
import { isIOS } from "./../utils/index.mjs";
|
|
4
|
+
export function usePlayerApi(args) {
|
|
5
|
+
const touched = ref(false);
|
|
6
|
+
const fullscreenTarget = isIOS() ? args.videoRef : args.playerRef;
|
|
7
|
+
const { currentTime, playing, muted } = args.mediaApi;
|
|
8
|
+
const {
|
|
9
|
+
isFullscreen,
|
|
10
|
+
enter: enterFullscreen,
|
|
11
|
+
exit: exitFullscreen,
|
|
12
|
+
toggle: toggleFullscreen
|
|
13
|
+
} = useFullscreen(fullscreenTarget);
|
|
14
|
+
function play() {
|
|
15
|
+
playing.value = true;
|
|
16
|
+
}
|
|
17
|
+
function pause() {
|
|
18
|
+
playing.value = false;
|
|
19
|
+
}
|
|
20
|
+
function togglePlay() {
|
|
21
|
+
playing.value = !playing.value;
|
|
22
|
+
}
|
|
23
|
+
function seek(time) {
|
|
24
|
+
currentTime.value = time;
|
|
25
|
+
}
|
|
26
|
+
function mute() {
|
|
27
|
+
muted.value = true;
|
|
28
|
+
}
|
|
29
|
+
function unmute() {
|
|
30
|
+
muted.value = false;
|
|
31
|
+
}
|
|
32
|
+
watch(playing, () => {
|
|
33
|
+
if (!touched.value) {
|
|
34
|
+
touched.value = true;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
isFullscreen,
|
|
39
|
+
touched,
|
|
40
|
+
play,
|
|
41
|
+
pause,
|
|
42
|
+
togglePlay,
|
|
43
|
+
seek,
|
|
44
|
+
mute,
|
|
45
|
+
unmute,
|
|
46
|
+
enterFullscreen,
|
|
47
|
+
exitFullscreen,
|
|
48
|
+
toggleFullscreen
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Ref } from 'vue';
|
|
2
|
+
import type { UsePlayerArgs } from './../types.js';
|
|
3
|
+
export type UseRuntimeSourceProviderReturn = {
|
|
4
|
+
loaded: Ref<boolean>;
|
|
5
|
+
};
|
|
6
|
+
type UseRuntimeSourceProviderArgs = Pick<UsePlayerArgs, 'videoRef' | 'srcType' | 'src'>;
|
|
7
|
+
export declare function useRuntimeSourceProvider(args: UseRuntimeSourceProviderArgs): UseRuntimeSourceProviderReturn;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { toValue } from "@vueuse/shared";
|
|
2
|
+
import { ref, onMounted, onUnmounted } from "vue";
|
|
3
|
+
export function useRuntimeSourceProvider(args) {
|
|
4
|
+
let hls;
|
|
5
|
+
const loaded = ref(false);
|
|
6
|
+
const useNative = () => {
|
|
7
|
+
const el = toValue(args.videoRef);
|
|
8
|
+
if (!el)
|
|
9
|
+
return;
|
|
10
|
+
el.src = args.src;
|
|
11
|
+
el.addEventListener(
|
|
12
|
+
"loadeddata",
|
|
13
|
+
() => {
|
|
14
|
+
loaded.value = true;
|
|
15
|
+
},
|
|
16
|
+
{ once: true }
|
|
17
|
+
);
|
|
18
|
+
el.load();
|
|
19
|
+
};
|
|
20
|
+
const useHlsJS = async () => {
|
|
21
|
+
const el = toValue(args.videoRef);
|
|
22
|
+
if (!el)
|
|
23
|
+
return;
|
|
24
|
+
const { default: Hls } = await import("hls.js");
|
|
25
|
+
hls = new Hls();
|
|
26
|
+
if (!Hls.isSupported()) {
|
|
27
|
+
useNative();
|
|
28
|
+
} else {
|
|
29
|
+
hls.loadSource(args.src);
|
|
30
|
+
hls.attachMedia(el);
|
|
31
|
+
hls.on(Hls.Events.FRAG_LOADED, () => {
|
|
32
|
+
loaded.value = true;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
onMounted(() => {
|
|
37
|
+
if (args.srcType === "native") {
|
|
38
|
+
useNative();
|
|
39
|
+
} else if (args.srcType === "hls") {
|
|
40
|
+
useHlsJS();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
onUnmounted(() => {
|
|
44
|
+
hls?.destroy();
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
loaded
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { MaybeRef } from '@vueuse/core';
|
|
2
|
+
type SourceType = 'native' | 'hls';
|
|
3
|
+
type UseControlsArgs = {
|
|
4
|
+
barRef?: MaybeRef<HTMLDivElement | undefined>;
|
|
5
|
+
trackRef: MaybeRef<HTMLDivElement | undefined>;
|
|
6
|
+
popoverRef?: MaybeRef<HTMLDivElement | undefined>;
|
|
7
|
+
};
|
|
8
|
+
type UsePlayerArgs = {
|
|
9
|
+
playerRef: MaybeRef<HTMLElement | undefined>;
|
|
10
|
+
videoRef: MaybeRef<HTMLVideoElement | undefined>;
|
|
11
|
+
srcType: SourceType;
|
|
12
|
+
src: string;
|
|
13
|
+
};
|
|
14
|
+
export * from './injectionKeys.js';
|
|
15
|
+
export type { SourceType, UseControlsArgs, UsePlayerArgs };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./injectionKeys.mjs";
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { InjectionKey } from 'vue';
|
|
2
|
+
import type { UseRuntimeSourceProviderReturn } from '../composables/useRuntimeSourceProvider.js';
|
|
3
|
+
declare const MediaApiInjectionKey: InjectionKey<{
|
|
4
|
+
currentTime: import("vue").Ref<number>;
|
|
5
|
+
duration: import("vue").Ref<number>;
|
|
6
|
+
waiting: import("vue").Ref<boolean>;
|
|
7
|
+
seeking: import("vue").Ref<boolean>;
|
|
8
|
+
ended: import("vue").Ref<boolean>;
|
|
9
|
+
stalled: import("vue").Ref<boolean>;
|
|
10
|
+
buffered: import("vue").Ref<[number, number][]>;
|
|
11
|
+
playing: import("vue").Ref<boolean>;
|
|
12
|
+
rate: import("vue").Ref<number>;
|
|
13
|
+
volume: import("vue").Ref<number>;
|
|
14
|
+
muted: import("vue").Ref<boolean>;
|
|
15
|
+
}>;
|
|
16
|
+
declare const PlayerApiInjectionKey: InjectionKey<{
|
|
17
|
+
isFullscreen: import("vue").Ref<boolean>;
|
|
18
|
+
touched: import("vue").Ref<boolean>;
|
|
19
|
+
play: () => void;
|
|
20
|
+
pause: () => void;
|
|
21
|
+
togglePlay: () => void;
|
|
22
|
+
seek: (time: number) => void;
|
|
23
|
+
mute: () => void;
|
|
24
|
+
unmute: () => void;
|
|
25
|
+
enterFullscreen: () => Promise<void>;
|
|
26
|
+
exitFullscreen: () => Promise<void>;
|
|
27
|
+
toggleFullscreen: () => Promise<void>;
|
|
28
|
+
}>;
|
|
29
|
+
declare const RuntimeSourceProviderInjectionKey: InjectionKey<UseRuntimeSourceProviderReturn>;
|
|
30
|
+
declare const ControlsApiInjectionKey: InjectionKey<{
|
|
31
|
+
entered: import("vue").Ref<boolean>;
|
|
32
|
+
dragging: import("vue").Ref<boolean>;
|
|
33
|
+
seekedTime: import("vue").Ref<number>;
|
|
34
|
+
seekedPercentage: import("vue").Ref<number>;
|
|
35
|
+
scrubbedPercentage: import("vue").Ref<number>;
|
|
36
|
+
bufferedPercentage: import("vue").ComputedRef<number>;
|
|
37
|
+
thumbPercentage: import("vue").Ref<number>;
|
|
38
|
+
popoverOffsetX: import("vue").Ref<number>;
|
|
39
|
+
onMouseEnter: () => void;
|
|
40
|
+
onMouseLeave: () => void;
|
|
41
|
+
onPointerDown: (e: MouseEvent | TouchEvent) => void;
|
|
42
|
+
onPointerUp: () => void;
|
|
43
|
+
onPointerMove: (e: MouseEvent | TouchEvent) => void;
|
|
44
|
+
}>;
|
|
45
|
+
export { MediaApiInjectionKey, PlayerApiInjectionKey, RuntimeSourceProviderInjectionKey, ControlsApiInjectionKey, };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const MediaApiInjectionKey = Symbol();
|
|
2
|
+
const PlayerApiInjectionKey = Symbol();
|
|
3
|
+
const RuntimeSourceProviderInjectionKey = Symbol();
|
|
4
|
+
const ControlsApiInjectionKey = Symbol();
|
|
5
|
+
export {
|
|
6
|
+
MediaApiInjectionKey,
|
|
7
|
+
PlayerApiInjectionKey,
|
|
8
|
+
RuntimeSourceProviderInjectionKey,
|
|
9
|
+
ControlsApiInjectionKey
|
|
10
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function formatTime(s: number): string;
|
|
2
|
+
export declare function clampValue(value: number, min: number, max: number): number;
|
|
3
|
+
export declare function mapValue(value: number, inMin: number, inMax: number, outMin: number, outMax: number): number;
|
|
4
|
+
export declare function isIOS(): boolean;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function formatTime(s) {
|
|
2
|
+
const hours = Math.floor(s / 3600);
|
|
3
|
+
const minutes = Math.floor((s - hours * 3600) / 60);
|
|
4
|
+
const seconds = Math.floor(s - hours * 3600 - minutes * 60);
|
|
5
|
+
const minutesString = minutes < 10 ? `0${minutes}` : `${minutes}`;
|
|
6
|
+
const secondsString = seconds < 10 ? `0${seconds}` : `${seconds}`;
|
|
7
|
+
return `${hours > 0 ? `${hours}:` : ""}${minutesString}:${secondsString}`;
|
|
8
|
+
}
|
|
9
|
+
export function clampValue(value, min, max) {
|
|
10
|
+
return value <= min ? min : value >= max ? max : value;
|
|
11
|
+
}
|
|
12
|
+
export function mapValue(value, inMin, inMax, outMin, outMax) {
|
|
13
|
+
return (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
|
|
14
|
+
}
|
|
15
|
+
export function isIOS() {
|
|
16
|
+
if (typeof window === "undefined")
|
|
17
|
+
return false;
|
|
18
|
+
return /iPad|iPhone|iPod/.test(navigator?.userAgent);
|
|
19
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { useEmitter } from './src/composables/useEmitter.js';
|
|
2
|
+
import { useProgress } from './src/composables/useProgress.js';
|
|
3
|
+
import { useCollisionDetect } from './src/composables/useCollisionDetect.js';
|
|
4
|
+
import type { Plugin } from 'vue';
|
|
5
|
+
export type * from './src/types';
|
|
6
|
+
declare const MagicScroll: Plugin;
|
|
7
|
+
export { MagicScroll, useEmitter, useProgress, useCollisionDetect };
|