move.gl 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.
Files changed (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -0
  3. package/css/move.gl.css +2 -0
  4. package/css/move.gl.min.css +2 -0
  5. package/package.json +55 -0
  6. package/scss/classes/_animations.scss +576 -0
  7. package/scss/classes/_index.scss +0 -0
  8. package/scss/classes/_transforms.scss +124 -0
  9. package/scss/classes/keyboard.scss +18 -0
  10. package/scss/classes/screensaver.scss +15 -0
  11. package/scss/dev/_banner.scss +36 -0
  12. package/scss/dev/_debug.scss +18 -0
  13. package/scss/dev/_deprecation.scss +10 -0
  14. package/scss/dev/_index.scss +8 -0
  15. package/scss/dev/_modules.scss +24 -0
  16. package/scss/effects/_filter.scss +176 -0
  17. package/scss/effects/_index.scss +23 -0
  18. package/scss/effects/_opacity.scss +62 -0
  19. package/scss/effects/_shadow.scss +175 -0
  20. package/scss/functions/_index.scss +0 -0
  21. package/scss/functions/scenes/_bubble.scss +19 -0
  22. package/scss/functions/scenes/_index.scss +20 -0
  23. package/scss/index.scss +0 -0
  24. package/scss/keyframes/_beat.scss +26 -0
  25. package/scss/keyframes/_index.scss +0 -0
  26. package/scss/maps/_index.scss +0 -0
  27. package/scss/maps/_mouse.scss +96 -0
  28. package/scss/mixins/_accessibility.scss +70 -0
  29. package/scss/mixins/_boot.scss +51 -0
  30. package/scss/mixins/_hover.scss +51 -0
  31. package/scss/mixins/_index.scss +0 -0
  32. package/scss/mixins/_selection.scss +321 -0
  33. package/scss/mixins/_shape.scss +44 -0
  34. package/scss/mixins/_touch.scss +95 -0
  35. package/scss/mixins/animations/--hover.scss +107 -0
  36. package/scss/mixins/animations/_base.scss +337 -0
  37. package/scss/mixins/animations/_beat.scss +119 -0
  38. package/scss/mixins/animations/_blink.scss +151 -0
  39. package/scss/mixins/animations/_bounce.scss +192 -0
  40. package/scss/mixins/animations/_elastic.scss +65 -0
  41. package/scss/mixins/animations/_fade.scss +154 -0
  42. package/scss/mixins/animations/_flash.scss +177 -0
  43. package/scss/mixins/animations/_flip.scss +72 -0
  44. package/scss/mixins/animations/_float.scss +126 -0
  45. package/scss/mixins/animations/_glow.scss +179 -0
  46. package/scss/mixins/animations/_heartbeat.scss +175 -0
  47. package/scss/mixins/animations/_hinge.scss +119 -0
  48. package/scss/mixins/animations/_index.scss +37 -0
  49. package/scss/mixins/animations/_jello.scss +129 -0
  50. package/scss/mixins/animations/_jiggle.scss +163 -0
  51. package/scss/mixins/animations/_lightspeed.scss +130 -0
  52. package/scss/mixins/animations/_nod.scss +161 -0
  53. package/scss/mixins/animations/_pop.scss +150 -0
  54. package/scss/mixins/animations/_pulse.scss +213 -0
  55. package/scss/mixins/animations/_ripple.scss +169 -0
  56. package/scss/mixins/animations/_roll.scss +261 -0
  57. package/scss/mixins/animations/_rotate.scss +428 -0
  58. package/scss/mixins/animations/_rubber.scss +116 -0
  59. package/scss/mixins/animations/_scale.scss +113 -0
  60. package/scss/mixins/animations/_shake.scss +182 -0
  61. package/scss/mixins/animations/_slide.scss +294 -0
  62. package/scss/mixins/animations/_spin.scss +219 -0
  63. package/scss/mixins/animations/_sway.scss +167 -0
  64. package/scss/mixins/animations/_swing.scss +247 -0
  65. package/scss/mixins/animations/_tada.scss +233 -0
  66. package/scss/mixins/animations/_twist.scss +177 -0
  67. package/scss/mixins/animations/_wave.scss +166 -0
  68. package/scss/mixins/animations/_wobble.scss +254 -0
  69. package/scss/mixins/animations/_zoom.scss +166 -0
  70. package/scss/mixins/effects/_filter.scss +148 -0
  71. package/scss/mixins/effects/_index.scss +0 -0
  72. package/scss/mixins/effects/_shadow.scss +21 -0
  73. package/scss/mixins/loaders/_index.scss +0 -0
  74. package/scss/mixins/loaders/_progress.scss +174 -0
  75. package/scss/mixins/loaders/_spinner.scss +101 -0
  76. package/scss/mixins/loaders/circle_01.scss +22 -0
  77. package/scss/mixins/loaders/circle_02.scss +19 -0
  78. package/scss/mixins/loaders/circle_03.scss +29 -0
  79. package/scss/mixins/loaders/circle_inner_01.scss +33 -0
  80. package/scss/mixins/loaders/circle_inner_02.scss +33 -0
  81. package/scss/mixins/loaders/circle_inner_03.scss +34 -0
  82. package/scss/mixins/mouse/_cursor.scss +182 -0
  83. package/scss/mixins/mouse/_index.scss +0 -0
  84. package/scss/mixins/mouse/_pointer.scss +258 -0
  85. package/scss/mixins/scroll/_index.scss +0 -0
  86. package/scss/mixins/scroll/_scroll.scss +104 -0
  87. package/scss/mixins/scroll/_scrollbar.scss +249 -0
  88. package/scss/mixins/transforms/_flip.scss +76 -0
  89. package/scss/mixins/transforms/_index.scss +23 -0
  90. package/scss/mixins/transforms/_matrix.scss +1 -0
  91. package/scss/mixins/transforms/_perspective.scss +11 -0
  92. package/scss/mixins/transforms/_rotate.scss +101 -0
  93. package/scss/mixins/transforms/_scale.scss +11 -0
  94. package/scss/mixins/transforms/_skew.scss +13 -0
  95. package/scss/mixins/transforms/_translate.scss +13 -0
  96. package/scss/mixins/transitions/_index.scss +0 -0
  97. package/scss/mixins/transitions/_transition.scss +13 -0
  98. package/scss/variables/_animation.scss +91 -0
  99. package/scss/variables/_index.scss +0 -0
  100. package/ts/ARContent.ts +27 -0
  101. package/ts/ARInteraction.ts +34 -0
  102. package/ts/AdaptiveUI.ts +25 -0
  103. package/ts/ContentStreaming.ts +20 -0
  104. package/ts/Draggable.ts +71 -0
  105. package/ts/DynamicEnvironment.ts +60 -0
  106. package/ts/Gesture.ts +168 -0
  107. package/ts/ImmersiveAudio.ts +40 -0
  108. package/ts/InteractiveCanvas.ts +177 -0
  109. package/ts/InteractiveVideo.ts +29 -0
  110. package/ts/Keyboard.ts +162 -0
  111. package/ts/RealTimeCollaboration.ts +25 -0
  112. package/ts/Screensaver.ts +140 -0
  113. package/ts/SpatialNavigation.ts +38 -0
  114. package/ts/UserProfile.ts +27 -0
  115. package/ts/VRExperience.ts +58 -0
  116. package/ts/VideoOverlay.ts +116 -0
  117. package/ts/index.ts +0 -0
package/ts/Keyboard.ts ADDED
@@ -0,0 +1,162 @@
1
+ // Copyright 2024 Scape Agency BV
2
+
3
+
4
+ /**
5
+ * @title Virtual Keyboard
6
+ * @notice Manages the rendering and interaction of a virtual keyboard on
7
+ * the web.
8
+ * @dev This class supports multiple layouts (default, shift, special) and
9
+ * handles both mouse and keyboard inputs, including touch support.
10
+ */
11
+ class VirtualKeyboard {
12
+
13
+ private keys: { [mode: string]: string[][] } = {
14
+ 'default': [
15
+ ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
16
+ ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'],
17
+ ['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'],
18
+ ['z', 'x', 'c', 'v', 'b', 'n', 'm', 'Backspace']
19
+ ],
20
+ 'shift': [
21
+ ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')'],
22
+ ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],
23
+ ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'],
24
+ ['Z', 'X', 'C', 'V', 'B', 'N', 'M', 'Backspace']
25
+ ],
26
+ 'special': [
27
+ ['[', ']', '{', '}', '#', '%', '^', '*', '+', '='],
28
+ ['_', '\\', '|', '~', '<', '>', '€', '£', '¥'],
29
+ ['.', ',', '?', '!', "'", '"', ':', ';', 'Backspace']
30
+ ]
31
+ };
32
+ private currentMode = 'default';
33
+ private inputElement: HTMLInputElement;
34
+ private keyboardElement: HTMLElement;
35
+
36
+ /**
37
+ * @notice Initializes the virtual keyboard with specific input and
38
+ * keyboard element IDs.
39
+ * @param inputId The ID of the HTML input element to which the keyboard
40
+ * will be linked.
41
+ * @param keyboardId The ID of the container element where the keyboard
42
+ * will be rendered.
43
+ */
44
+ constructor(inputId: string, keyboardId: string) {
45
+ this.inputElement = document.getElementById(
46
+ inputId
47
+ ) as HTMLInputElement;
48
+ this.keyboardElement = document.getElementById(
49
+ keyboardId
50
+ ) as HTMLElement;
51
+ this.renderKeyboard();
52
+ this.attachEventListeners();
53
+ }
54
+
55
+ /**
56
+ * @notice Renders the keyboard based on the current mode (default, shift,
57
+ * or special).
58
+ * @dev Dynamically creates HTML for keyboard keys and appends them to the
59
+ * keyboardElement.
60
+ */
61
+ private renderKeyboard() {
62
+ // Clear existing keys
63
+ this.keyboardElement.innerHTML = '';
64
+ this.keys[this.currentMode].forEach(row => {
65
+ const rowElement = document.createElement('div');
66
+ row.forEach(key => {
67
+ const keyElement = document.createElement('div');
68
+ keyElement.textContent = key;
69
+ // Assign a class for easier CSS styling
70
+ keyElement.className = 'key';
71
+ keyElement.addEventListener(
72
+ 'click', () => this.handleKeyPress(key)
73
+ );
74
+ rowElement.appendChild(keyElement);
75
+ });
76
+ this.keyboardElement.appendChild(rowElement);
77
+ });
78
+ }
79
+
80
+ /**
81
+ * @notice Handles key presses on the virtual keyboard.
82
+ * @param key The key character or function (like 'Backspace') that was
83
+ * pressed.
84
+ */
85
+ private handleKeyPress(key: string) {
86
+ if (key === 'Backspace') {
87
+ this.inputElement.value = this.inputElement.value.slice(0, -1);
88
+ } else if (key === 'Shift' || key === 'CapsLock') {
89
+ this.toggleShift();
90
+ } else {
91
+ this.inputElement.value += key;
92
+ }
93
+ }
94
+
95
+ /**
96
+ * @notice Toggles the keyboard between 'default' and 'shift' modes.
97
+ * @dev This method is called when the 'Shift' or 'CapsLock' key is pressed.
98
+ */
99
+ private toggleShift() {
100
+ this.currentMode = this.currentMode === 'default' ? 'shift' : 'default';
101
+ this.renderKeyboard();
102
+ }
103
+
104
+ /**
105
+ * @notice Attaches necessary event listeners to handle both physical
106
+ * keyboard and touch inputs.
107
+ */
108
+ private attachEventListeners() {
109
+ document.addEventListener('keydown', this.handlePhysicalKeyPress);
110
+ this.keyboardElement.addEventListener(
111
+ 'touchstart', this.handleTouchStart, false
112
+ );
113
+ }
114
+
115
+ /**
116
+ * @notice Handles physical keyboard events and maps them to virtual key
117
+ * presses.
118
+ * @param event The keyboard event captured from the user's physical
119
+ * keyboard.
120
+ */
121
+ private handlePhysicalKeyPress = (event: KeyboardEvent) => {
122
+ const key = event.key;
123
+ if (key === 'Shift' || key === 'CapsLock') {
124
+ this.toggleShift();
125
+ event.preventDefault();
126
+ } else if (key === 'Enter' || key === 'Tab') {
127
+ // Optional: Implement behavior for Enter and Tab if needed
128
+ } else {
129
+ this.handleKeyPress(key);
130
+ }
131
+ };
132
+
133
+ /**
134
+ * @notice Handles touch events on the keyboard element.
135
+ * @param event The touch event on the virtual keyboard.
136
+ */
137
+ private handleTouchStart = (event: TouchEvent) => {
138
+ event.preventDefault(); // Prevents emulating mouse events
139
+ const keyElement = event.target as HTMLElement;
140
+ if (keyElement.classList.contains('key')) {
141
+ this.handleKeyPress(keyElement.textContent || '');
142
+ }
143
+ };
144
+
145
+ /**
146
+ * @notice Switches the keyboard layout to a specified mode.
147
+ * @param mode The mode to which the keyboard layout should switch
148
+ * ('default', 'shift', or 'special').
149
+ */
150
+ public switchMode(mode: string) {
151
+ if (this.keys[mode]) {
152
+ this.currentMode = mode;
153
+ this.renderKeyboard();
154
+ }
155
+ }
156
+ }
157
+
158
+ // Example usage:
159
+ const keyboard = new VirtualKeyboard('textInput', 'keyboard');
160
+ document.getElementById(
161
+ 'switchToSpecial'
162
+ ).addEventListener('click', () => keyboard.switchMode('special'));
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @title Real-Time Collaboration Handler
3
+ * @notice Facilitates real-time interaction and collaboration in virtual environments.
4
+ * @dev Leverages WebSockets or WebRTC to synchronize user activities across different sessions.
5
+ */
6
+ class RealTimeCollaborationHandler {
7
+ private socket: WebSocket;
8
+
9
+ constructor(serverUrl: string) {
10
+ this.socket = new WebSocket(serverUrl);
11
+ this.socket.onmessage = this.handleMessage;
12
+ this.socket.onopen = () => console.log("Connection established for real-time collaboration.");
13
+ }
14
+
15
+ private handleMessage = (message: MessageEvent) => {
16
+ const data = JSON.parse(message.data);
17
+ console.log("Received data for collaboration:", data);
18
+ // Process and apply data to the collaborative environment
19
+ }
20
+
21
+ public sendUpdate(data: object) {
22
+ this.socket.send(JSON.stringify(data));
23
+ console.log("Sent update:", data);
24
+ }
25
+ }
@@ -0,0 +1,140 @@
1
+ // Copyright 2024 Scape Agency BV
2
+
3
+
4
+ /**
5
+ * @title Screensaver Class
6
+ * @notice Handles the activation and deactivation of a screensaver based on
7
+ * user inactivity.
8
+ * @dev This class provides methods to start and stop the screensaver, manage
9
+ * media sources, and handle user interactions.
10
+ */
11
+ class Screensaver {
12
+
13
+ private timeoutId: number | undefined;
14
+ private readonly timeout: number;
15
+ private screensaverElement: HTMLElement | undefined;
16
+ private videoElement: HTMLVideoElement | undefined;
17
+ private audioElement: HTMLAudioElement | undefined;
18
+ private isActive: boolean = false;
19
+
20
+ /**
21
+ * @notice Initializes a new Screensaver instance.
22
+ * @param timeout The inactivity timeout in milliseconds after which the
23
+ * screensaver activates.
24
+ * @param videoUrl The URL for the video to be played when the screensaver
25
+ * activates.
26
+ * @param audioUrl The URL for the audio to be played when the screensaver
27
+ * activates.
28
+ */
29
+ constructor(timeout: number, videoUrl: string, audioUrl: string) {
30
+ this.timeout = timeout;
31
+ this.initializeElements();
32
+ this.loadMedia(videoUrl, audioUrl);
33
+ this.setupEventListeners();
34
+ }
35
+
36
+ /**
37
+ * @notice Initializes HTML elements from the DOM.
38
+ * @dev Queries the DOM to get the screensaver, video, and audio elements
39
+ * by their IDs.
40
+ */
41
+ private initializeElements() {
42
+ this.screensaverElement = document.getElementById("screensaver")!;
43
+ this.videoElement = document.getElementById(
44
+ "screensaverVideo"
45
+ ) as HTMLVideoElement;
46
+ this.audioElement = document.getElementById(
47
+ "screensaverAudio"
48
+ ) as HTMLAudioElement;
49
+ }
50
+
51
+ /**
52
+ * @notice Loads media sources into the video and audio elements.
53
+ * @param videoUrl The source URL of the video.
54
+ * @param audioUrl The source URL of the audio.
55
+ */
56
+ private loadMedia(videoUrl: string, audioUrl: string) {
57
+ this.videoElement.src = videoUrl;
58
+ this.audioElement.src = audioUrl;
59
+ }
60
+
61
+ /**
62
+ * @notice Sets up event listeners for user interaction to prevent
63
+ * screensaver activation.
64
+ * @dev Listens for 'mousemove', 'keydown', and 'touchstart' events
65
+ * to reset the screensaver timer.
66
+ */
67
+ private setupEventListeners() {
68
+ ['mousemove', 'keydown', 'touchstart'].forEach(event => {
69
+ document.addEventListener(event, this.resetScreensaver);
70
+ });
71
+ }
72
+
73
+ /**
74
+ * @notice Starts or restarts the screensaver timeout.
75
+ * @dev Resets any existing timeout and sets a new timeout to activate
76
+ * the screensaver.
77
+ */
78
+ private startScreensaverTimeout() {
79
+ this.stopScreensaver(); // Stop existing screensaver if active
80
+ this.timeoutId = window.setTimeout(
81
+ () => this.activateScreensaver(), this.timeout
82
+ );
83
+ }
84
+
85
+ /**
86
+ * @notice Resets the screensaver timer and stops the screensaver if
87
+ * active.
88
+ * @dev Called upon user interactions detected by event listeners.
89
+ */
90
+ private resetScreensaver = () => {
91
+ if (this.isActive) {
92
+ this.stopScreensaver();
93
+ }
94
+ this.startScreensaverTimeout();
95
+ };
96
+
97
+ /**
98
+ * @notice Activates the screensaver, displaying elements and playing media.
99
+ */
100
+ private activateScreensaver = () => {
101
+ this.screensaverElement.style.display = 'block';
102
+ this.videoElement.play();
103
+ this.audioElement.play();
104
+ this.isActive = true;
105
+ };
106
+
107
+ /**
108
+ * @notice Stops the screensaver and hides its elements.
109
+ * @dev Pauses media playback and clears the activation timeout.
110
+ */
111
+ private stopScreensaver() {
112
+ this.screensaverElement.style.display = 'none';
113
+ this.videoElement.pause();
114
+ this.audioElement.pause();
115
+ this.isActive = false;
116
+
117
+ if (this.timeoutId !== undefined) {
118
+ clearTimeout(this.timeoutId);
119
+ this.timeoutId = undefined;
120
+ }
121
+ }
122
+
123
+ /**
124
+ * @notice Sets the volume for both video and audio elements of the
125
+ * screensaver.
126
+ * @param volume A number between 0.0 and 1.0 indicating the volume level.
127
+ */
128
+ public setVolume(volume: number) {
129
+ this.videoElement.volume = volume;
130
+ this.audioElement.volume = volume;
131
+ }
132
+ }
133
+
134
+ // Example usage:
135
+ const screensaver = new Screensaver(
136
+ 300000,
137
+ 'path/to/video.mp4',
138
+ 'path/to/audio.mp3'
139
+ ); // Initialize the screensaver with a 5-minute timeout
140
+ screensaver.setVolume(0.5); // Set initial volume to 50%
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @title Spatial Navigation Handler
3
+ * @notice Provides navigation controls for moving through a 3D space or virtual environments.
4
+ * @dev Supports both keyboard and other input methods for movement and rotation in a 3D space.
5
+ */
6
+ class SpatialNavigationHandler {
7
+ private position: { x: number; y: number; z: number } = { x: 0, y: 0, z: 0 };
8
+ private rotation: { yaw: number; pitch: number; roll: number } = { yaw: 0, pitch: 0, roll: 0 };
9
+
10
+ constructor() {
11
+ document.addEventListener('keydown', this.handleKeyInput);
12
+ }
13
+
14
+ private handleKeyInput = (event: KeyboardEvent) => {
15
+ switch(event.key) {
16
+ case 'ArrowUp':
17
+ this.position.y += 1; // Move up
18
+ break;
19
+ case 'ArrowDown':
20
+ this.position.y -= 1; // Move down
21
+ break;
22
+ case 'ArrowLeft':
23
+ this.rotation.yaw -= 5; // Turn left
24
+ break;
25
+ case 'ArrowRight':
26
+ this.rotation.yaw += 5; // Turn right
27
+ break;
28
+ case 'w':
29
+ this.position.z += 1; // Move forward
30
+ break;
31
+ case 's':
32
+ this.position.z -= 1; // Move backward
33
+ break;
34
+ // Add more controls as needed
35
+ }
36
+ console.log(`Position: (${this.position.x}, ${this.position.y}, ${this.position.z}), Rotation: (${this.rotation.yaw}, ${this.rotation.pitch}, ${this.rotation.roll})`);
37
+ };
38
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @title User Profile and Preferences Handler
3
+ * @notice Manages user-specific settings and preferences for an immersive web application.
4
+ * @dev Stores and retrieves user preferences from local storage or a remote database.
5
+ */
6
+ class UserProfileHandler {
7
+ private preferences: Map<string, any> = new Map();
8
+
9
+ constructor() {
10
+ this.loadPreferences();
11
+ }
12
+
13
+ private loadPreferences() {
14
+ console.log("Loading user preferences...");
15
+ // Load preferences from local storage or a database.
16
+ }
17
+
18
+ public setPreference(key: string, value: any) {
19
+ this.preferences.set(key, value);
20
+ console.log(`Preference ${key} set to`, value);
21
+ // Optionally save to local storage or update the database.
22
+ }
23
+
24
+ public getPreference(key: string) {
25
+ return this.preferences.get(key);
26
+ }
27
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @title VR Experience Handler
3
+ * @notice Manages Virtual Reality scenes and interactions using WebXR.
4
+ * @dev Provides an easy interface to setup, control, and interact with VR content.
5
+ */
6
+ class VRExperienceHandler {
7
+ private xrSession: XRSession | null = null;
8
+
9
+ constructor(private container: HTMLElement) {
10
+ if ('xr' in navigator) {
11
+ this.initVR();
12
+ } else {
13
+ console.error("WebXR not available.");
14
+ }
15
+ }
16
+
17
+ private async initVR() {
18
+ try {
19
+ this.xrSession = await navigator.xr.requestSession('immersive-vr', {
20
+ optionalFeatures: ['local-floor', 'bounded-floor']
21
+ });
22
+ this.xrSession.addEventListener('end', this.onSessionEnded);
23
+ this.setupXRWebGLLayer();
24
+ } catch (error) {
25
+ console.error("Failed to create XR Session: ", error);
26
+ }
27
+ }
28
+
29
+ private setupXRWebGLLayer() {
30
+ const gl = this.container.querySelector('canvas')!.getContext('webgl2')!;
31
+ this.xrSession!.updateRenderState({
32
+ baseLayer: new XRWebGLLayer(this.xrSession, gl)
33
+ });
34
+ }
35
+
36
+ private onSessionEnded = () => {
37
+ console.log("VR session ended.");
38
+ this.xrSession = null;
39
+ }
40
+
41
+ public startRendering() {
42
+ if (!this.xrSession) {
43
+ console.error("XR Session is not initialized.");
44
+ return;
45
+ }
46
+
47
+ this.xrSession.requestAnimationFrame((time, frame) => this.renderFrame(time, frame));
48
+ }
49
+
50
+ private renderFrame(time: DOMHighResTimeStamp, frame: XRFrame) {
51
+ const session = frame.session;
52
+ const pose = frame.getViewerPose(xrReferenceSpace);
53
+
54
+ if (pose) {
55
+ // Update your scene's rendering based on user's position
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,116 @@
1
+ // Copyright 2024 Scape Agency BV
2
+
3
+ /**
4
+ * @title Transparent Video Overlay Handler
5
+ * @notice Manages a transparent video overlay, controlling its visibility,
6
+ * playback, and effects.
7
+ * @dev Provides methods to show, hide, toggle, and dynamically change the
8
+ * video source with visual effects.
9
+ */
10
+ class TransparentVideoOverlay {
11
+ private videoElement: HTMLVideoElement;
12
+ private isVisible: boolean = false;
13
+
14
+ constructor(videoElementId: string) {
15
+ this.videoElement = document.getElementById(
16
+ videoElementId
17
+ ) as HTMLVideoElement;
18
+ this.setupVideo();
19
+ }
20
+
21
+ /**
22
+ * @notice Initializes video settings and event listeners for enhanced
23
+ * control.
24
+ */
25
+ private setupVideo() {
26
+ this.videoElement.addEventListener(
27
+ "ended", () => this.videoElement.play()
28
+ ); // Ensure looping
29
+ this.videoElement.addEventListener("loadeddata", () => {
30
+ console.log("Video loaded successfully.");
31
+ });
32
+ this.videoElement.addEventListener("error", (e) => {
33
+ console.error("Error loading video:", e);
34
+ });
35
+ }
36
+
37
+ /**
38
+ * @notice Shows the video overlay with a fade-in effect.
39
+ * @dev Uses CSS transitions to create a fade-in effect.
40
+ */
41
+ public showOverlay() {
42
+ this.videoElement.style.display = "block";
43
+ this.videoElement.style.opacity = "0";
44
+ setTimeout(() => {
45
+ this.videoElement.style.opacity = "1";
46
+ this.videoElement.play();
47
+ }, 10); // Timeout to ensure CSS transition takes place
48
+ this.isVisible = true;
49
+ }
50
+
51
+ /**
52
+ * @notice Hides the video overlay with a fade-out effect.
53
+ * @dev Uses CSS transitions to create a fade-out effect before pausing
54
+ * and hiding the video.
55
+ */
56
+ public hideOverlay() {
57
+ this.videoElement.style.opacity = "0";
58
+ setTimeout(() => {
59
+ this.videoElement.style.display = "none";
60
+ this.videoElement.pause();
61
+ }, 500); // Match timeout to CSS transition duration
62
+ this.isVisible = false;
63
+ }
64
+
65
+ /**
66
+ * @notice Toggles the visibility of the video overlay with effects.
67
+ */
68
+ public toggleOverlay() {
69
+ if (this.isVisible) {
70
+ this.hideOverlay();
71
+ } else {
72
+ this.showOverlay();
73
+ }
74
+ }
75
+
76
+ /**
77
+ * @notice Changes the video source and optionally plays it immediately.
78
+ * @param videoUrl The URL of the new video source.
79
+ * @param autoPlay Determines if the video should play immediately after
80
+ * loading.
81
+ */
82
+ public changeVideoSource(videoUrl: string, autoPlay: boolean = true) {
83
+ this.videoElement.src = videoUrl;
84
+ this.videoElement.load(); // Reload video to apply new source
85
+ if (autoPlay) {
86
+ this.showOverlay();
87
+ }
88
+ }
89
+ }
90
+
91
+ // Example usage:
92
+ const videoOverlay = new TransparentVideoOverlay("videoOverlay");
93
+ videoOverlay.showOverlay(); // Show the overlay with fade-in effect
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
+ function supportsHEVCAlpha() {
102
+ const navigator = window.navigator;
103
+ const ua = navigator.userAgent.toLowerCase()
104
+ const hasMediaCapabilities = !!(navigator.mediaCapabilities && navigator.mediaCapabilities.decodingInfo)
105
+ const isSafari = ((ua.indexOf("safari") != -1) && (!(ua.indexOf("chrome")!= -1) && (ua.indexOf("version/")!= -1)))
106
+ return isSafari && hasMediaCapabilities
107
+ }
108
+
109
+ // Here’s an example of how this comes together in HTML:
110
+
111
+ <video id="player" loop muted autoplay playsinline></video>
112
+
113
+ <script>
114
+ const player = document.getElementById("player");
115
+ player.src = supportsHEVCAlpha() ? "output.mov" : "output.webm";
116
+ </script>
package/ts/index.ts ADDED
File without changes