Refactoring: split into directories

This commit is contained in:
Dejvino
2025-11-16 13:25:42 +01:00
parent 1c2a3c6d3a
commit 1f3f5b372c
8 changed files with 13 additions and 13 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
import * as THREE from 'three';
import { state } from '../state.js';
import { updateVcrDisplay } from '../vcr-display.js';
import { updateVcrDisplay } from '../scene/vcr-display.js';
function updateCamera() {
+3 -3
View File
@@ -1,9 +1,9 @@
import * as THREE from 'three';
import { state, initState } from '../state.js';
import { EffectsManager } from '../EffectsManager.js';
import { createSceneObjects } from '../scene.js';
import { EffectsManager } from '../effects/EffectsManager.js';
import { createSceneObjects } from '../scene/scene.js';
import { animate, onWindowResize } from './animate.js';
import { loadVideoFile, playNextVideo } from '../video-player.js';
import { loadVideoFile, playNextVideo } from './video-player.js';
// --- Initialization ---
export function init() {
+115
View File
@@ -0,0 +1,115 @@
import * as THREE from 'three';
import { state } from '../state.js';
// --- Play video by index ---
export function playVideoByIndex(index) {
state.currentVideoIndex = index;
const url = state.videoUrls[index];
// Dispose of previous texture to free resources
if (state.videoTexture) {
state.videoTexture.dispose();
state.videoTexture = null;
}
if (index < 0 || index >= state.videoUrls.length) {
console.info('End of playlist reached. Reload tapes to start again.');
state.screenLight.intensity = 0.0;
state.tvScreen.material.dispose();
state.tvScreen.material = new THREE.MeshPhongMaterial({
color: 0x0a0a0a, // Deep black
shininess: 5,
specular: 0x111111
});
state.tvScreen.material.needsUpdate = true;
state.isVideoLoaded = false;
state.lastUpdateTime = -1; // force VCR to redraw
return;
}
state.videoElement.src = url;
state.videoElement.muted = true;
state.videoElement.load();
// Set loop property: only loop if it's the only video loaded
state.videoElement.loop = false; //state.videoUrls.length === 1;
state.videoElement.onloadeddata = () => {
// 1. Create the Three.js texture
state.videoTexture = new THREE.VideoTexture(state.videoElement);
state.videoTexture.minFilter = THREE.LinearFilter;
state.videoTexture.magFilter = THREE.LinearFilter;
state.videoTexture.format = THREE.RGBAFormat;
state.videoTexture.needsUpdate = true;
// 2. Apply the video texture to the screen mesh
state.tvScreen.material.dispose();
state.tvScreen.material = new THREE.MeshBasicMaterial({ map: state.videoTexture });
state.tvScreen.material.needsUpdate = true;
// 3. Start playback
state.videoElement.play().then(() => {
state.isVideoLoaded = true;
// Use the defined base intensity for screen glow
state.screenLight.intensity = state.originalScreenIntensity;
// Initial status message with tape count
console.info(`Playing tape ${state.currentVideoIndex + 1} of ${state.videoUrls.length}.`);
}).catch(error => {
state.screenLight.intensity = state.originalScreenIntensity * 0.5; // Dim the light if playback fails
console.error(`Playback blocked for tape ${state.currentVideoIndex + 1}. Click Next Tape to try again.`);
console.error('Playback Error: Could not start video playback.', error);
});
};
state.videoElement.onerror = (e) => {
state.screenLight.intensity = 0.1; // Keep minimum intensity for shadow map
console.error(`Error loading tape ${state.currentVideoIndex + 1}.`);
console.error('Video Load Error:', e);
};
}
// --- Cycle to the next video ---
export function playNextVideo() {
// Determine the next index, cycling back to 0 if we reach the end
let nextIndex = state.currentVideoIndex + 1;
if (nextIndex < state.videoUrls.length) {
state.baseTime += state.videoElement.duration;
}
playVideoByIndex(nextIndex);
}
// --- Video Loading Logic (handles multiple files) ---
export function loadVideoFile(event) {
const files = event.target.files;
if (files.length === 0) {
console.info('File selection cancelled.');
return;
}
// 1. Clear previous URLs and revoke object URLs to prevent memory leaks
state.videoUrls.forEach(url => URL.revokeObjectURL(url));
state.videoUrls = [];
// 2. Populate the new videoUrls array
for (let i = 0; i < files.length; i++) {
const file = files[i];
if (file.type.startsWith('video/')) {
state.videoUrls.push(URL.createObjectURL(file));
}
}
if (state.videoUrls.length === 0) {
console.info('No valid video files selected.');
return;
}
// 3. Start playback of the first video
console.info(`Loaded ${state.videoUrls.length} tapes. Starting playback...`);
state.loadTapeButton.classList.add("hidden");
const startDelay = 5;
console.info(`Video will start in ${startDelay} seconds.`);
setTimeout(() => { playVideoByIndex(0); }, startDelay * 1000);
}