204 lines
5.8 KiB
JavaScript
204 lines
5.8 KiB
JavaScript
// var elements = document.querySelectorAll('.element');
|
|
|
|
// document.addEventListener('keydown', handler(elements.length - 1), false);
|
|
|
|
// elements[0].classList.add('active');
|
|
|
|
const canvas = document.getElementById('canvas');
|
|
const ctx = canvas.getContext('2d');
|
|
fitToContainer(canvas);
|
|
|
|
let wordsQueue = [];
|
|
let startTime = 0;
|
|
|
|
function fitToContainer(canvas){
|
|
// Make it visually fill the positioned parent
|
|
canvas.style.width ='100%';
|
|
canvas.style.height='100%';
|
|
// ...then set the internal size to match
|
|
canvas.width = canvas.offsetWidth;
|
|
canvas.height = canvas.offsetHeight;
|
|
}
|
|
|
|
canvas.style.display = "none"
|
|
|
|
document.addEventListener('keydown', function(event) {
|
|
// First, remove "active" from all buttons
|
|
|
|
|
|
// Now check which key was pressed and add "active" accordingly
|
|
if (event.key === 'a' || event.key === 'A') {
|
|
resetActive()
|
|
document.getElementById('button1').classList.add('active');
|
|
} else if (event.key === 's' || event.key === 'S') {
|
|
resetActive()
|
|
document.getElementById('button2').classList.add('active');
|
|
} else if (event.key === 'd' || event.key === 'D') {
|
|
resetActive()
|
|
document.getElementById('button3').classList.add('active');
|
|
}
|
|
else if (event.key === 'Enter') {
|
|
playAudio(document.querySelector('.menuButtons .element.active').innerHTML);
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
function resetActive(){
|
|
document.querySelectorAll('.menuButtons .element').forEach(button => {
|
|
button.classList.remove('active');
|
|
});
|
|
}
|
|
|
|
function playAudio(filename){
|
|
canvas.style.display = "block"
|
|
document.getElementById('safeArea').style.display = "flex";
|
|
document.getElementById('grid').style.display = "none";
|
|
|
|
|
|
|
|
document.getElementById('menuButtons').style.display = "none";
|
|
let audioContext;
|
|
let analyser;
|
|
let source;
|
|
let dataArray;
|
|
let bufferLength;
|
|
|
|
const TOTAL_BARS = 44 ; // Only 44 bars now
|
|
const BARS_AREA_WIDTH = 320; // Width of bars
|
|
const MAX_BAR_HEIGHT = 22; // Max bar height
|
|
|
|
// const audio = document.getElementById(filename);
|
|
const audio = new Audio(filename + ".mp3");
|
|
audio.controls = false;
|
|
document.body.appendChild(audio);
|
|
audio.play();
|
|
audio.onplay = function() {
|
|
startTime = Date.now();
|
|
showWords();
|
|
};
|
|
|
|
|
|
audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
|
source = audioContext.createMediaElementSource(audio);
|
|
analyser = audioContext.createAnalyser();
|
|
|
|
source.connect(analyser);
|
|
analyser.connect(audioContext.destination);
|
|
|
|
analyser.fftSize = 256;
|
|
bufferLength = analyser.frequencyBinCount;
|
|
dataArray = new Uint8Array(bufferLength);
|
|
|
|
animate();
|
|
|
|
audio.addEventListener('ended', (event) => {
|
|
canvas.style.display = "none"
|
|
document.getElementById('grid').style.display = "flex";
|
|
console.log('audio has been ended');
|
|
});
|
|
|
|
function animate() {
|
|
requestAnimationFrame(animate);
|
|
|
|
analyser.getByteFrequencyData(dataArray);
|
|
|
|
// Clear everything (no ghosting)
|
|
ctx.fillStyle = '#000000';
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
|
|
const step = Math.floor(bufferLength / TOTAL_BARS);
|
|
const barWidth = BARS_AREA_WIDTH / TOTAL_BARS;
|
|
const centerY = canvas.height / 2;
|
|
const centerX = (canvas.width - BARS_AREA_WIDTH) / 2;
|
|
|
|
// Draw center line
|
|
|
|
|
|
ctx.fillStyle = '#ffffff'; // White bars
|
|
|
|
// Store top bars heights
|
|
const barHeights = [];
|
|
|
|
// Draw top bars
|
|
for (let i = 0; i < TOTAL_BARS; i++) {
|
|
let sum = 0;
|
|
for (let j = 0; j < step; j++) {
|
|
sum += dataArray[(i * step) + j] || 0;
|
|
}
|
|
const average = sum / step;
|
|
|
|
const barHeight = (average / 255) * MAX_BAR_HEIGHT;
|
|
barHeights.push(barHeight); // Save for mirroring
|
|
|
|
ctx.fillRect(centerX + i * barWidth, centerY-2 - barHeight, barWidth, barHeight);
|
|
}
|
|
|
|
// Draw bottom bars (mirror of top)
|
|
for (let i = 0; i < TOTAL_BARS; i++) {
|
|
const mirroredHeight = barHeights[i];
|
|
ctx.fillRect(centerX + i * barWidth, centerY+2, barWidth, mirroredHeight);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//Subtitle processing part use showWords();
|
|
|
|
|
|
|
|
// Parse SRT text into words with timing
|
|
function parseSRT(data) {
|
|
const regex = /(\d+)\s+(\d{2}:\d{2}:\d{2},\d{3}) --> (\d{2}:\d{2}:\d{2},\d{3})\s+(.+?)(?:\r?\n|$)/gs;
|
|
let matches;
|
|
const result = [];
|
|
while ((matches = regex.exec(data)) !== null) {
|
|
result.push({
|
|
start: timeStringToMs(matches[2]),
|
|
end: timeStringToMs(matches[3]),
|
|
text: matches[4].trim()
|
|
});
|
|
}
|
|
console.log(result);
|
|
return result;
|
|
|
|
}
|
|
|
|
// Convert SRT time format to milliseconds
|
|
function timeStringToMs(timeStr) {
|
|
const [hours, minutes, seconds] = timeStr.split(':');
|
|
const [secs, ms] = seconds.split(',');
|
|
return (+hours) * 3600000 + (+minutes) * 60000 + (+secs) * 1000 + (+ms);
|
|
}
|
|
|
|
// Show words at correct times
|
|
function showWords() {
|
|
const now = Date.now() - startTime;
|
|
const subtitleDiv = document.getElementById('element');
|
|
|
|
if (wordsQueue.length > 0 && now >= wordsQueue[0].start) {
|
|
const nextWord = wordsQueue.shift();
|
|
subtitleDiv.innerHTML += (subtitleDiv.innerHTML ? ' ' : '') + nextWord.text;
|
|
}
|
|
|
|
requestAnimationFrame(showWords);
|
|
}
|
|
|
|
// Load SRT and start
|
|
window.addEventListener('DOMContentLoaded', function() {
|
|
fetch('option1.srt') // Adjust path if necessary
|
|
.then(response => {
|
|
return response.text();
|
|
})
|
|
.then(data => {
|
|
wordsQueue = parseSRT(data);
|
|
// document.getElementById('subtitle').innerHTML = '';
|
|
|
|
})
|
|
.catch(error => {
|
|
console.error('Failed to load subtitles:', error);
|
|
});
|
|
}); |