void;
export class Jukebox {
parser: SRTParser;
listener: AudioListener;
@@ -26,14 +38,14 @@ export class Jukebox {
const music = await LoadAudio(
this.listener,
"/static/music/space_chillout.mp3",
- 1,
+ 0.5,
"music",
- true
+ false
);
const poem = await LoadAudio(
this.listener,
"/static/music/who_am_i.mp3",
- 1,
+ 0.7,
"poem",
false
);
@@ -43,13 +55,11 @@ export class Jukebox {
const poemAnalyser = new AudioAnalyser(poem, 512);
const startButton = document.getElementById("startButton");
- startButton.style.display = "block";
startButton.addEventListener("click", () => {
silence.play();
music.play();
poem.play();
- // CORE.playing = true;
startButton.remove();
clickCallback();
});
@@ -79,16 +89,3 @@ export class Jukebox {
}
}
}
-
-type SRTParser = {
- (srt: string): SRT[];
-};
-
-type SRT = {
- id: number;
- start: number;
- end: number;
- text: string;
-};
-
-type ClickCallback = () => void;
diff --git a/src/actors/Planets.ts b/src/actors/Planets.ts
index 8c6b3d9..fbfcc86 100644
--- a/src/actors/Planets.ts
+++ b/src/actors/Planets.ts
@@ -6,8 +6,16 @@ import {
SphereBufferGeometry,
Vector3,
} from "three";
-import { calculateSoundAverages } from "../audio";
+import { calculateSoundAverages } from "../utils/audioUtils";
+export interface Planet extends Mesh {
+ geometry: SphereBufferGeometry;
+ material: MeshToonMaterial;
+ originalPosition?: Vector3;
+ offsetY?: number;
+ angleSpeed?: number;
+ angle?: number;
+}
export class Planets {
meshes: Array
;
analyser: AudioAnalyser;
@@ -56,12 +64,3 @@ export class Planets {
});
}
}
-
-export interface Planet extends Mesh {
- geometry: SphereBufferGeometry;
- material: MeshToonMaterial;
- originalPosition?: Vector3;
- offsetY?: number;
- angleSpeed?: number;
- angle?: number;
-}
diff --git a/src/audio.ts b/src/audio.ts
deleted file mode 100644
index 01abdec..0000000
--- a/src/audio.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import {
- Audio,
- AudioAnalyser,
- AudioListener,
- AudioLoader,
- PositionalAudio,
-} from "three";
-import { avg, chunk } from "./utils";
-
-const loader = new AudioLoader();
-
-export function LoadAudio(
- listener: AudioListener,
- url: string,
- volume: number,
- type: string,
- positional?: boolean
-): Promise {
- const loadingDiv = document.getElementById("loader");
- loadingDiv.innerHTML = `Loading ${type}: 0%`;
-
- return new Promise((resolve, reject) => {
- loader.load(
- url,
- (audio) => {
- const sound = positional
- ? new PositionalAudio(listener)
- : new Audio(listener);
- sound.setBuffer(audio);
- sound.setLoop(false);
- sound.setVolume(volume);
- loadingDiv.innerHTML = "";
- return resolve(sound);
- },
- (progress) =>
- (loadingDiv.innerHTML = `Loading audio: ${
- (progress.loaded / progress.total) * 100
- }%`),
- (error: ErrorEvent) => {
- console.log(error.target);
- reject(error);
- }
- );
- });
-}
-
-export function calculateSoundAverages(
- audioAnalyser: AudioAnalyser,
- chunkAmount: number
-): number[] {
- const soundArray = audioAnalyser.getFrequencyData();
- const chunkedArray = chunk(soundArray, chunkAmount);
- const averages = chunkedArray.map((arr) => avg(arr) / 255);
-
- return averages;
-}
diff --git a/src/index.ts b/src/index.ts
index 51183aa..1f1d184 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -12,7 +12,6 @@ import {
PerspectiveCamera,
} from "three";
import { GLTF } from "three/examples/jsm/loaders/GLTFLoader";
-import { LoadModel } from "./model";
import { prng_alea } from "esm-seedrandom";
import parseSRT from "parse-srt";
import { Planets } from "./actors/Planets";
@@ -20,6 +19,20 @@ import { OrbitCamera } from "./actors/OrbitCamera";
import { Hand } from "./actors/Hand";
import { OrbitLight } from "./actors/OrbitLight";
import { Jukebox } from "./actors/Jukebox";
+import { LoadModel } from "./utils/loaders";
+
+interface CORE {
+ renderer: WebGLRenderer;
+ scene: Scene;
+ clock: Clock;
+ rng: RandomNumberGenerator;
+ playing: boolean;
+ audioListener: AudioListener;
+}
+
+export type RandomNumberGenerator = {
+ (): number;
+};
const CORE: CORE = {
renderer: null,
@@ -38,7 +51,9 @@ let HAND: Hand;
let PLANETS: Planets;
let JUKEBOX: Jukebox;
-init().then(() => animate());
+init()
+ .then(() => animate())
+ .catch((err) => console.warn(err));
async function init() {
const container = document.getElementById("container");
@@ -70,13 +85,15 @@ async function init() {
CORE.playing = true;
});
CORE.scene.add(poem);
- ORBIT_LIGHT.light.add(music);
+ CORE.scene.add(music);
const model = await LoadModel();
initializeModel(model, poemAnalyser);
initializeStars();
ORBIT_CAMERA.update(0, HAND.mesh.position);
PLANETS = new Planets(musicAnalyser);
PLANETS.meshes.forEach((planet) => CORE.scene.add(planet));
+ document.getElementById("loader").innerHTML = "";
+ document.getElementById("startButton").style.display = "block";
} catch (err) {
console.warn(err);
}
@@ -133,16 +150,3 @@ function onWindowResize() {
CORE.renderer.setSize(window.innerWidth, window.innerHeight);
}
-
-interface CORE {
- renderer: WebGLRenderer;
- scene: Scene;
- clock: Clock;
- rng: RandomNumberGenerator;
- playing: boolean;
- audioListener: AudioListener;
-}
-
-export type RandomNumberGenerator = {
- (): number;
-};
diff --git a/src/model.ts b/src/model.ts
deleted file mode 100644
index 5d38abd..0000000
--- a/src/model.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import { Texture, TextureLoader } from "three";
-import { GLTFLoader, GLTF } from "three/examples/jsm/loaders/GLTFLoader.js";
-
-const gltfLoader = new GLTFLoader();
-const textureLoader = new TextureLoader();
-
-export function LoadModel(): Promise {
- const loadingDiv = document.getElementById("loader");
- return new Promise((resolve, reject) => {
- gltfLoader.load(
- "/static/models/scene.gltf",
- (gltf: GLTF) => {
- loadingDiv.innerHTML = "";
- resolve(gltf);
- },
- (progress) =>
- (loadingDiv.innerHTML = `Loading model: ${
- (progress.loaded / progress.total) * 100
- }%`),
- (error: ErrorEvent) => {
- console.log(error.target);
- reject(error);
- }
- );
- });
-}
-
-export function LoadTexture(url): Promise {
- const loadingDiv = document.getElementById("loader");
- return new Promise((resolve, reject) => {
- textureLoader.load(
- url,
- (texture: Texture) => resolve(texture),
- (progress) =>
- (loadingDiv.innerHTML = `Loading texture: ${
- (progress.loaded / progress.total) * 100
- }%`),
- (error: ErrorEvent) => {
- console.log(error.target);
- reject(error);
- }
- );
- });
-}
diff --git a/src/utils.ts b/src/utils/arrayUtils.ts
similarity index 100%
rename from src/utils.ts
rename to src/utils/arrayUtils.ts
diff --git a/src/utils/audioUtils.ts b/src/utils/audioUtils.ts
new file mode 100644
index 0000000..8597439
--- /dev/null
+++ b/src/utils/audioUtils.ts
@@ -0,0 +1,13 @@
+import { AudioAnalyser } from "three";
+import { avg, chunk } from "./arrayUtils";
+
+export function calculateSoundAverages(
+ audioAnalyser: AudioAnalyser,
+ chunkAmount: number
+): number[] {
+ const soundArray = audioAnalyser.getFrequencyData();
+ const chunkedArray = chunk(soundArray, chunkAmount);
+ const averages = chunkedArray.map((arr) => avg(arr) / 255);
+
+ return averages;
+}
diff --git a/src/utils/loaders.ts b/src/utils/loaders.ts
new file mode 100644
index 0000000..022a5ba
--- /dev/null
+++ b/src/utils/loaders.ts
@@ -0,0 +1,61 @@
+import { Audio, AudioListener, AudioLoader, PositionalAudio } from "three";
+import { GLTFLoader, GLTF } from "three/examples/jsm/loaders/GLTFLoader.js";
+
+const loader = new AudioLoader();
+const gltfLoader = new GLTFLoader();
+
+export function LoadAudio(
+ listener: AudioListener,
+ url: string,
+ volume: number,
+ type: string,
+ positional?: boolean
+): Promise {
+ const loadingDiv = document.getElementById("loader");
+ loadingDiv.innerHTML = `Loading ${type}: 0.00%`;
+
+ return new Promise((resolve, reject) => {
+ loader.load(
+ url,
+ (audio) => {
+ const sound = positional
+ ? new PositionalAudio(listener)
+ : new Audio(listener);
+ sound.setBuffer(audio);
+ sound.setLoop(false);
+ sound.setVolume(volume);
+ return resolve(sound);
+ },
+ (progress) => {
+ const percent = (progress.loaded / progress.total) * 100;
+ loadingDiv.innerHTML = `Loading ${type}: ${percent.toFixed(2)}%`;
+ },
+ (error: ErrorEvent) => {
+ console.log(error.target);
+ reject(error);
+ }
+ );
+ });
+}
+
+export function LoadModel(): Promise {
+ const loadingDiv = document.getElementById("loader");
+ loadingDiv.innerHTML = `Loading model: 0.00%`;
+
+ return new Promise((resolve, reject) => {
+ gltfLoader.load(
+ "/static/models/scene.gltf",
+ (gltf: GLTF) => {
+ resolve(gltf);
+ },
+ (progress) => {
+ const percent = (progress.loaded / progress.total) * 100;
+ loadingDiv.innerHTML = `Loading model: ${percent.toFixed(2)}%`;
+ },
+ (error: ErrorEvent) => {
+ console.log(error.target);
+ reject(error);
+ }
+ );
+ });
+}
diff --git a/static/og.png b/static/og.png
index d16f13d..618748c 100644
Binary files a/static/og.png and b/static/og.png differ