refactored - still some renedering issue
This commit is contained in:
parent
ac58c0e8c3
commit
17f1cbfa9b
|
|
@ -27,7 +27,7 @@ function fadeOutVolume() {
|
|||
gainNode.gain.linearRampToValueAtTime(0, audioContext.currentTime + 2); // Fade to 0
|
||||
}
|
||||
|
||||
function playSound(instrument) {
|
||||
export function playSound(instrument) {
|
||||
if (interacted) {
|
||||
// const source = audioContext.createBufferSource();
|
||||
const samples = instrument.samples;
|
||||
|
|
|
|||
|
|
@ -1,22 +1,15 @@
|
|||
import { loadInstruments } from "./instruments.js";
|
||||
|
||||
export class Conductor {
|
||||
instruments;
|
||||
|
||||
constructor() {}
|
||||
|
||||
showingWhichContent;
|
||||
interacted = true;
|
||||
cleanUpAndRestart(reload = false) {
|
||||
const icons = document.querySelectorAll(".event-icon");
|
||||
const timeIndicator = document.getElementById("time-indicator");
|
||||
icons.forEach((icon) => {
|
||||
icon.classList.add("fade-out");
|
||||
icon.addEventListener("transitionend", () => {
|
||||
icon.remove();
|
||||
});
|
||||
});
|
||||
currStaveNumber = 1;
|
||||
setTitle();
|
||||
if (reload) location.reload();
|
||||
|
||||
get instruments() {
|
||||
return this.instruments;
|
||||
}
|
||||
|
||||
setTitle() {
|
||||
|
|
@ -93,45 +86,19 @@ export class Conductor {
|
|||
|
||||
async init() {
|
||||
const instrumentsKey = document.getElementById("instrument-key-div");
|
||||
const instruments = await loadInstruments();
|
||||
const instNames = Object.keys(instruments);
|
||||
this.instruments = await loadInstruments();
|
||||
const instNames = Object.keys(this.instruments);
|
||||
for (const instrument of instNames) {
|
||||
const keyDiv = document.createElement("div");
|
||||
const keySvg = document.createElement("object");
|
||||
const keyName = document.createElement("div");
|
||||
keyName.innerText = instrument.toUpperCase();
|
||||
keySvg.type = "image/svg+xml";
|
||||
keySvg.data = instruments[instrument].image;
|
||||
keySvg.data = this.instruments[instrument].image;
|
||||
keyDiv.appendChild(keySvg);
|
||||
keyDiv.appendChild(keyName);
|
||||
keyDiv.classList.add("instrument-key");
|
||||
instrumentsKey.appendChild(keyDiv);
|
||||
}
|
||||
|
||||
const numStaves = 6;
|
||||
const sheetWindow = document.getElementById("music-window");
|
||||
|
||||
for (let i = 1; i <= numStaves; i++) {
|
||||
const staveWrapper = document.createElement("div");
|
||||
staveWrapper.classList.add(`stave-wrapper`);
|
||||
staveWrapper.setAttribute("id", `stave-wrapper-${i}`);
|
||||
staveWrapper.style.position = "relative";
|
||||
const staveObject = document.createElement("object");
|
||||
staveObject.type = "image/svg+xml";
|
||||
staveObject.data = "assets/svg/stave.svg";
|
||||
staveObject.classList.add("stave-svg");
|
||||
|
||||
staveWrapper.appendChild(staveObject);
|
||||
sheetWindow.appendChild(staveWrapper);
|
||||
}
|
||||
|
||||
const timeIndicator = document.querySelector("#time-indicator");
|
||||
|
||||
timeIndicator.addEventListener("animationiteration", () => {
|
||||
currStaveNumber++;
|
||||
if (currStaveNumber > numStaves) {
|
||||
cleanUpAndRestart();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
105
src/render.js
105
src/render.js
|
|
@ -1,32 +1,83 @@
|
|||
const placeIcon = (instrument) => {
|
||||
if (currStaveNumber > numStaves) currStaveNumber = 1;
|
||||
// Select the staveWrapper in which to place the div
|
||||
const staveWrapper = document.getElementById(
|
||||
`stave-wrapper-${currStaveNumber}`
|
||||
);
|
||||
// Determine the position of the time indicator
|
||||
const rect = timeIndicator.getBoundingClientRect();
|
||||
const sheetLeft = sheetWindow.getBoundingClientRect().left;
|
||||
const xPosition = rect.left + window.scrollX - sheetLeft;
|
||||
export class Renderer {
|
||||
timeIndicator;
|
||||
currStaveNumber;
|
||||
numStaves;
|
||||
sheetWindow;
|
||||
|
||||
// Create the icon div and give it its location data
|
||||
const newObject = document.createElement("div");
|
||||
newObject.classList.add("event-icon");
|
||||
newObject.style.position = "absolute";
|
||||
constructor() {
|
||||
this.numStaves = 6;
|
||||
this.currStaveNumber = 1; // ✅ Initialize current stave number
|
||||
this.timeIndicator = document.querySelector("#time-indicator");
|
||||
|
||||
newObject.style.left = `${
|
||||
xPosition - document.documentElement.clientWidth / 200
|
||||
}px`;
|
||||
newObject.style.top = `${instrument.yPos}`;
|
||||
this.timeIndicator.addEventListener("animationiteration", () => {
|
||||
this.currStaveNumber++;
|
||||
if (this.currStaveNumber > this.numStaves) {
|
||||
this.cleanUpAndRestart(); // ✅ Use this.method
|
||||
}
|
||||
});
|
||||
|
||||
// Create the icon
|
||||
const eventIcon = document.createElement("object");
|
||||
eventIcon.type = "image/svg+xml";
|
||||
eventIcon.data = instrument.image;
|
||||
this.sheetWindow = document.getElementById("music-window");
|
||||
|
||||
// Append icon to div
|
||||
newObject.appendChild(eventIcon);
|
||||
for (let i = 1; i <= this.numStaves; i++) {
|
||||
const staveWrapper = document.createElement("div");
|
||||
staveWrapper.classList.add("stave-wrapper");
|
||||
staveWrapper.setAttribute("id", `stave-wrapper-${i}`);
|
||||
staveWrapper.style.position = "relative";
|
||||
|
||||
// Append the div to the staveWrapper
|
||||
staveWrapper.appendChild(newObject);
|
||||
};
|
||||
const staveObject = document.createElement("object");
|
||||
staveObject.type = "image/svg+xml";
|
||||
staveObject.data = "assets/svg/stave.svg";
|
||||
staveObject.classList.add("stave-svg");
|
||||
|
||||
staveWrapper.appendChild(staveObject);
|
||||
this.sheetWindow.appendChild(staveWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
placeIcon = (instrument) => {
|
||||
if (this.currStaveNumber > this.numStaves) this.currStaveNumber = 1;
|
||||
|
||||
// ✅ Use a local variable instead of overwriting this.staveWrapper
|
||||
const targetWrapper = document.getElementById(
|
||||
`stave-wrapper-${this.currStaveNumber}`
|
||||
);
|
||||
|
||||
const rect = this.timeIndicator.getBoundingClientRect();
|
||||
const sheetLeft = this.sheetWindow.getBoundingClientRect().left;
|
||||
const xPosition = rect.left + window.scrollX - sheetLeft;
|
||||
|
||||
const newObject = document.createElement("div");
|
||||
newObject.classList.add("event-icon");
|
||||
newObject.style.position = "absolute";
|
||||
newObject.style.left = `${
|
||||
xPosition - document.documentElement.clientWidth / 200
|
||||
}px`;
|
||||
newObject.style.top = `${instrument.yPos}`;
|
||||
|
||||
const eventIcon = document.createElement("object");
|
||||
eventIcon.type = "image/svg+xml";
|
||||
eventIcon.data = instrument.image;
|
||||
|
||||
newObject.appendChild(eventIcon);
|
||||
targetWrapper.appendChild(newObject); // ✅ Append to local reference
|
||||
};
|
||||
|
||||
cleanUpAndRestart(reload = false) {
|
||||
const icons = document.querySelectorAll(".event-icon");
|
||||
this.timeIndicator = document.getElementById("time-indicator");
|
||||
|
||||
icons.forEach((icon) => {
|
||||
icon.classList.add("fade-out");
|
||||
icon.addEventListener("transitionend", () => {
|
||||
icon.remove();
|
||||
});
|
||||
});
|
||||
|
||||
this.currStaveNumber = 1;
|
||||
|
||||
// Assuming setTitle() exists globally or is handled elsewhere
|
||||
setTitle();
|
||||
|
||||
if (reload) location.reload();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,36 @@
|
|||
import { sendMidiMessage } from "./midi.js";
|
||||
import { Conductor } from "./conductor.js";
|
||||
import { DataStream } from "./socket.js";
|
||||
import { playSound } from "./audio";
|
||||
import { Renderer, placeIcon } from "./render.js";
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
sendMidiMessage();
|
||||
|
||||
const conductor = new Conductor();
|
||||
await conductor.init();
|
||||
const dataStream = new DataStream();
|
||||
conductor.init();
|
||||
const instruments = await conductor.instruments;
|
||||
console.log(instruments);
|
||||
|
||||
const renderer = new Renderer();
|
||||
|
||||
dataStream.addEventListener("strike", () => {
|
||||
const keys = Object.keys(instruments);
|
||||
const randomIndex = Math.floor(Math.random() * keys.length);
|
||||
const selectedInstrument = instruments[keys[randomIndex]];
|
||||
|
||||
renderer.placeIcon(selectedInstrument);
|
||||
playSound(selectedInstrument);
|
||||
});
|
||||
|
||||
dataStream.init();
|
||||
|
||||
let currStaveNumber = 1;
|
||||
// let currStaveNumber = 1;
|
||||
|
||||
conductor.showMainContent();
|
||||
|
||||
let strikeNumber = 0;
|
||||
// let strikeNumber = 0;
|
||||
|
||||
// setupWebSocketListeners(); // Setup the WebSocket listeners
|
||||
// resetTimeout(); // Start the timeout timer
|
||||
|
|
|
|||
|
|
@ -1,79 +1,62 @@
|
|||
import { Client, BrowserSocketFactory } from "./blitz.js";
|
||||
export class DataStream {
|
||||
socketFactory;
|
||||
connectionTimeout;
|
||||
lastReceived;
|
||||
client;
|
||||
import { BrowserSocketFactory, Client } from "./blitz";
|
||||
|
||||
constructor() {}
|
||||
export class DataStream extends EventTarget {
|
||||
constructor() {
|
||||
super();
|
||||
this.socketFactory = null;
|
||||
this.client = null;
|
||||
this.lastReceived = null;
|
||||
this.connectionTimeout = null;
|
||||
}
|
||||
|
||||
async init() {
|
||||
this.socketFactory = new BrowserSocketFactory();
|
||||
this.lastReceived = Date.now(); // Tracks the last time data was received
|
||||
this.client = new Client(socketFactory);
|
||||
client.connect();
|
||||
setupWebSocketListeners();
|
||||
resetTimeout();
|
||||
this.client = new Client(this.socketFactory);
|
||||
this.lastReceived = Date.now();
|
||||
|
||||
this.setupWebSocketListeners();
|
||||
this.client.connect();
|
||||
this.resetTimeout();
|
||||
}
|
||||
|
||||
resetTimeout() {
|
||||
clearTimeout(connectionTimeout);
|
||||
connectionTimeout = setTimeout(() => {
|
||||
// 14 seconds of inactivity
|
||||
clearTimeout(this.connectionTimeout);
|
||||
this.connectionTimeout = setTimeout(() => {
|
||||
console.log("No data received in 14 seconds, reconnecting...");
|
||||
reconnectWebSocket();
|
||||
this.reconnectWebSocket();
|
||||
}, 14999);
|
||||
}
|
||||
|
||||
reconnectWebSocket() {
|
||||
console.log("Reconnecting WebSocket...");
|
||||
|
||||
// Clean up the existing WebSocket connection
|
||||
if (client) {
|
||||
client.close(); // Ensure the current connection is closed
|
||||
if (this.client) {
|
||||
this.client.close();
|
||||
}
|
||||
|
||||
// Create a new client instance and re-establish the connection
|
||||
client = new Client(new BrowserSocketFactory());
|
||||
setupWebSocketListeners(); // Set up listeners for the new WebSocket
|
||||
client.connect(); // Reconnect
|
||||
|
||||
// Reset timeout after reconnecting
|
||||
resetTimeout(); // Ensure timeout is re-established after reconnection
|
||||
this.client = new Client(new BrowserSocketFactory());
|
||||
this.setupWebSocketListeners();
|
||||
this.client.connect();
|
||||
this.resetTimeout();
|
||||
}
|
||||
|
||||
setupWebSocketListeners() {
|
||||
client.removeAllListeners("data");
|
||||
client.removeAllListeners("error");
|
||||
client.removeAllListeners("close");
|
||||
this.client.removeAllListeners?.("data");
|
||||
this.client.removeAllListeners?.("error");
|
||||
this.client.removeAllListeners?.("close");
|
||||
|
||||
client.on("data", (strike) => {
|
||||
lastReceived = Date.now(); // Update the last received timestamp
|
||||
resetTimeout(); // Reset the timeout on any data received
|
||||
this.client.on("data", (data) => {
|
||||
this.lastReceived = Date.now();
|
||||
this.resetTimeout();
|
||||
|
||||
// Process the strike (existing logic from your original code)
|
||||
strikeNumber++;
|
||||
if (strikeNumber == 0) {
|
||||
const randomInstrumentNumber = Math.floor(
|
||||
Math.random() * (Object.keys(instruments).length - 0)
|
||||
);
|
||||
const selectedInstrumentName =
|
||||
Object.keys(instruments)[randomInstrumentNumber];
|
||||
|
||||
placeIcon(instruments[selectedInstrumentName]);
|
||||
playSound(instruments[selectedInstrumentName]);
|
||||
strikeNumber = -1;
|
||||
}
|
||||
this.dispatchEvent(new CustomEvent("strike", { detail: data }));
|
||||
});
|
||||
|
||||
client.on("error", (message) => {
|
||||
console.log("WebSocket error:", message);
|
||||
reconnectWebSocket();
|
||||
this.client.on("error", (err) => {
|
||||
console.error("WebSocket error:", err);
|
||||
this.reconnectWebSocket();
|
||||
});
|
||||
|
||||
client.on("close", () => {
|
||||
this.client.on("close", () => {
|
||||
console.log("WebSocket closed, attempting to reconnect...");
|
||||
reconnectWebSocket();
|
||||
this.reconnectWebSocket();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue