Spaces:
Running
Running
Update index.html
Browse files- index.html +42 -31
index.html
CHANGED
|
@@ -154,17 +154,24 @@
|
|
| 154 |
}
|
| 155 |
|
| 156 |
#video-container {
|
| 157 |
-
width: 100%;
|
| 158 |
-
background-color: #000;
|
| 159 |
margin: 20px auto 0;
|
| 160 |
position: relative;
|
| 161 |
overflow: hidden;
|
| 162 |
border-radius: 8px;
|
| 163 |
display: none;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
}
|
| 165 |
|
| 166 |
-
#video-container.aspect-
|
| 167 |
-
|
|
|
|
|
|
|
|
|
|
| 168 |
|
| 169 |
#video-container img {
|
| 170 |
position: absolute;
|
|
@@ -316,15 +323,17 @@
|
|
| 316 |
const displayNextImage = () => {
|
| 317 |
if (imageElements.length === 0) return;
|
| 318 |
|
| 319 |
-
|
| 320 |
-
imageElements[lastIndex].classList.remove('active');
|
| 321 |
|
| 322 |
const activeIndex = currentImageIndex % imageElements.length;
|
| 323 |
const currentImg = imageElements[activeIndex];
|
| 324 |
|
| 325 |
-
currentImg.className = 'active kenburns';
|
| 326 |
const randomAnimation = KENBURNS_CLASSES[Math.floor(Math.random() * KENBURNS_CLASSES.length)];
|
| 327 |
-
currentImg.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
|
| 329 |
currentImageIndex++;
|
| 330 |
};
|
|
@@ -338,12 +347,20 @@
|
|
| 338 |
displayNextImage();
|
| 339 |
slideInterval = setInterval(displayNextImage, SLIDE_DURATION_MS);
|
| 340 |
};
|
| 341 |
-
|
| 342 |
const startRecording = () => {
|
| 343 |
const ctx = canvas.getContext('2d');
|
| 344 |
const stream = canvas.captureStream(30);
|
| 345 |
recordedChunks = [];
|
| 346 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 347 |
|
| 348 |
mediaRecorder.ondataavailable = event => {
|
| 349 |
if (event.data.size > 0) recordedChunks.push(event.data);
|
|
@@ -365,17 +382,7 @@
|
|
| 365 |
recordingInterval = setInterval(() => {
|
| 366 |
const activeImg = document.querySelector('#video-container img.active');
|
| 367 |
if (activeImg) {
|
| 368 |
-
|
| 369 |
-
const imgRect = activeImg.getBoundingClientRect();
|
| 370 |
-
const scaleX = activeImg.width / imgRect.width;
|
| 371 |
-
const scaleY = activeImg.height / imgRect.height;
|
| 372 |
-
|
| 373 |
-
const dx = (imgRect.left - containerRect.left) * scaleX;
|
| 374 |
-
const dy = (imgRect.top - containerRect.top) * scaleY;
|
| 375 |
-
const dWidth = containerRect.width * scaleX;
|
| 376 |
-
const dHeight = containerRect.height * scaleY;
|
| 377 |
-
|
| 378 |
-
ctx.drawImage(activeImg, dx, dy, dWidth, dHeight, 0, 0, canvas.width, canvas.height);
|
| 379 |
}
|
| 380 |
}, 1000 / 30);
|
| 381 |
};
|
|
@@ -401,14 +408,18 @@
|
|
| 401 |
setStatus('Preparando imágenes...', 'processing');
|
| 402 |
|
| 403 |
videoContainer.innerHTML = '';
|
| 404 |
-
imageElements = Array.from(files).map(file => {
|
| 405 |
-
const img = document.createElement('img');
|
| 406 |
-
img.src = URL.createObjectURL(file);
|
| 407 |
-
videoContainer.appendChild(img);
|
| 408 |
-
return img;
|
| 409 |
-
});
|
| 410 |
|
| 411 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 412 |
const utterance = new SpeechSynthesisUtterance(text);
|
| 413 |
utterance.lang = langSelect.value;
|
| 414 |
|
|
@@ -416,8 +427,8 @@
|
|
| 416 |
setStatus('Reproduciendo y grabando video...', 'processing');
|
| 417 |
|
| 418 |
const [w, h] = aspectRatioSelect.value.split(':').map(Number);
|
| 419 |
-
canvas.width = 1280;
|
| 420 |
-
canvas.height =
|
| 421 |
|
| 422 |
startSlideshow();
|
| 423 |
startRecording();
|
|
@@ -438,7 +449,7 @@
|
|
| 438 |
};
|
| 439 |
|
| 440 |
window.speechSynthesis.speak(utterance);
|
| 441 |
-
}
|
| 442 |
});
|
| 443 |
|
| 444 |
window.addEventListener('beforeunload', stopAllProcesses);
|
|
|
|
| 154 |
}
|
| 155 |
|
| 156 |
#video-container {
|
|
|
|
|
|
|
| 157 |
margin: 20px auto 0;
|
| 158 |
position: relative;
|
| 159 |
overflow: hidden;
|
| 160 |
border-radius: 8px;
|
| 161 |
display: none;
|
| 162 |
+
background-color: #000;
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
#video-container.aspect-16-9 {
|
| 166 |
+
width: 100%;
|
| 167 |
+
aspect-ratio: 16 / 9;
|
| 168 |
}
|
| 169 |
|
| 170 |
+
#video-container.aspect-9-16 {
|
| 171 |
+
height: 65vh;
|
| 172 |
+
aspect-ratio: 9 / 16;
|
| 173 |
+
max-width: 100%;
|
| 174 |
+
}
|
| 175 |
|
| 176 |
#video-container img {
|
| 177 |
position: absolute;
|
|
|
|
| 323 |
const displayNextImage = () => {
|
| 324 |
if (imageElements.length === 0) return;
|
| 325 |
|
| 326 |
+
imageElements.forEach(img => img.classList.remove('active'));
|
|
|
|
| 327 |
|
| 328 |
const activeIndex = currentImageIndex % imageElements.length;
|
| 329 |
const currentImg = imageElements[activeIndex];
|
| 330 |
|
|
|
|
| 331 |
const randomAnimation = KENBURNS_CLASSES[Math.floor(Math.random() * KENBURNS_CLASSES.length)];
|
| 332 |
+
currentImg.className = 'kenburns ' + randomAnimation;
|
| 333 |
+
|
| 334 |
+
setTimeout(() => {
|
| 335 |
+
currentImg.classList.add('active');
|
| 336 |
+
}, 50);
|
| 337 |
|
| 338 |
currentImageIndex++;
|
| 339 |
};
|
|
|
|
| 347 |
displayNextImage();
|
| 348 |
slideInterval = setInterval(displayNextImage, SLIDE_DURATION_MS);
|
| 349 |
};
|
| 350 |
+
|
| 351 |
const startRecording = () => {
|
| 352 |
const ctx = canvas.getContext('2d');
|
| 353 |
const stream = canvas.captureStream(30);
|
| 354 |
recordedChunks = [];
|
| 355 |
+
|
| 356 |
+
const options = { mimeType: 'video/webm; codecs=vp9' };
|
| 357 |
+
if (!MediaRecorder.isTypeSupported(options.mimeType)) {
|
| 358 |
+
options.mimeType = 'video/webm; codecs=vp8';
|
| 359 |
+
if (!MediaRecorder.isTypeSupported(options.mimeType)) {
|
| 360 |
+
options.mimeType = 'video/webm';
|
| 361 |
+
}
|
| 362 |
+
}
|
| 363 |
+
mediaRecorder = new MediaRecorder(stream, options);
|
| 364 |
|
| 365 |
mediaRecorder.ondataavailable = event => {
|
| 366 |
if (event.data.size > 0) recordedChunks.push(event.data);
|
|
|
|
| 382 |
recordingInterval = setInterval(() => {
|
| 383 |
const activeImg = document.querySelector('#video-container img.active');
|
| 384 |
if (activeImg) {
|
| 385 |
+
ctx.drawImage(activeImg, 0, 0, canvas.width, canvas.height);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 386 |
}
|
| 387 |
}, 1000 / 30);
|
| 388 |
};
|
|
|
|
| 408 |
setStatus('Preparando imágenes...', 'processing');
|
| 409 |
|
| 410 |
videoContainer.innerHTML = '';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 411 |
|
| 412 |
+
const imageLoadPromises = Array.from(files).map(file => {
|
| 413 |
+
return new Promise((resolve) => {
|
| 414 |
+
const img = document.createElement('img');
|
| 415 |
+
img.src = URL.createObjectURL(file);
|
| 416 |
+
img.onload = () => resolve(img);
|
| 417 |
+
videoContainer.appendChild(img);
|
| 418 |
+
});
|
| 419 |
+
});
|
| 420 |
+
|
| 421 |
+
Promise.all(imageLoadPromises).then(loadedImages => {
|
| 422 |
+
imageElements = loadedImages;
|
| 423 |
const utterance = new SpeechSynthesisUtterance(text);
|
| 424 |
utterance.lang = langSelect.value;
|
| 425 |
|
|
|
|
| 427 |
setStatus('Reproduciendo y grabando video...', 'processing');
|
| 428 |
|
| 429 |
const [w, h] = aspectRatioSelect.value.split(':').map(Number);
|
| 430 |
+
canvas.width = w === 9 ? 720 : 1280;
|
| 431 |
+
canvas.height = w === 9 ? 1280 : 720;
|
| 432 |
|
| 433 |
startSlideshow();
|
| 434 |
startRecording();
|
|
|
|
| 449 |
};
|
| 450 |
|
| 451 |
window.speechSynthesis.speak(utterance);
|
| 452 |
+
});
|
| 453 |
});
|
| 454 |
|
| 455 |
window.addEventListener('beforeunload', stopAllProcesses);
|