You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

161 lines
5.9 KiB

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Projector View</title>
<style>
body {
font-family: Futura, sans-serif;
font-size: 32px;
background-color: green;
color: white;
text-align: center; /* Align text to the left */
margin: 0;
padding: 0;
-webkit-text-fill-color: white;
-webkit-text-stroke-color: black;
/*-webkit-text-stroke-width: 6.00px; */
paint-order: stroke fill;
}
#container {
overflow: hidden;
height: 200px; /* Ensure container is tall enough for 4 lines */
width: 42ch;
position: relative;
padding-left: 20px; /* Add some padding to the left */
margin-left: auto;
margin-right: auto;
}
#content {
position: relative;
top: 0;
left: auto;
right: auto;
/*transition: top 0.5s ease;*/ /* Smooth scrolling */
}
.line {
opacity: 1;
min-height: 44px;
white-space: normal; /* Allow lines to wrap */
word-wrap: break-word; /* Break long words if needed */
margin: 5px 0;
line-height: 48px;
}
.line span {
background-color: rgba(0, 0, 0, 0.7);
padding: 2px;
}
.currentLine {
font-weight: bold;
opacity: 1;
}
/* Ensure there's space for 4 lines to be displayed */
#container {
max-height: 400px;
}
</style>
</head>
<body>
<div id="container">
<div id="content"></div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
const contentElement = document.getElementById('content');
let speechLines = [];
let currentLineIndex = 0;
// Display 4 lines (previous, current, next, and an extra one above the current line)
function updateDisplay() {
contentElement.innerHTML = ''; // Clear previous lines
const start = Math.max(0, currentLineIndex - 2); // Show 2 lines before current
const end = Math.min(speechLines.length, currentLineIndex + 2); // Show 2 lines after current
// Create a new block of lines
const displayLines = speechLines.slice(start, end).map((line, index) => {
const div = document.createElement('div');
div.classList.add('line');
if (index === 2) div.classList.add('currentLine'); // Highlight the current line
const span = document.createElement('span');
span.textContent = line;
div.appendChild(span);
return div;
});
displayLines.forEach(div => contentElement.appendChild(div));
// Scroll animation based on the height of each line
const lineHeight = document.querySelector('.line').offsetHeight;
const previousLinesHeight = (currentLineIndex - start - 1) * lineHeight; // Offset for lines above the current line
contentElement.style.top = `-${previousLinesHeight}px`;
}
// Receive updates from the server
socket.on('update_caption', (newPosition) => {
currentLineIndex = newPosition;
updateDisplay();
});
// Load the speech when a new client connects
socket.on('load_speech', (lines) => {
speechLines = lines;
currentLineIndex = 0;
updateDisplay(); // Display the initial lines
});
// Update audience text based on live typing
socket.on('live_typing', (text) => {
const lines = text.split('\n'); // Split by new lines
const fullLines = lines.slice(-3); // Get the last three lines
// Check if the last line is complete
let lastLine = fullLines[fullLines.length - 1];
const isLastWordComplete = lastLine.endsWith(' ') || lastLine.endsWith('.') || lastLine.endsWith(',') || lastLine.endsWith('!') || lastLine.endsWith('?') || lastLine.endsWith('\n');
// If the last word is not complete, hide it
if (!isLastWordComplete) {
lastLine = lastLine.trim().split(' ').slice(0, -1).join(' '); // Remove the last word
}
// Join back the lines and update content
contentElement.innerHTML = '';
// Create a new block of lines
let displayLines = (fullLines.slice(0, -1)).map((line, index) => {
const div = document.createElement('div');
div.classList.add('line');
const span = document.createElement('span');
span.textContent = line;
div.appendChild(span);
return div;
});
const lastLineDiv = document.createElement('div');
lastLineDiv.classList.add('line');
lastLineDiv.classList.add('currentLine');
const lastLineSpan = document.createElement('span');
lastLineSpan.textContent = lastLine;
lastLineDiv.appendChild(lastLineSpan);
displayLines.push(lastLineDiv)
displayLines.forEach(div => contentElement.appendChild(div));
// Scroll animation based on the height of each line
//const lineHeight = document.querySelector('.line').offsetHeight;
//const previousLinesHeight = (currentLineIndex - start - 1) * lineHeight; // Offset for lines above the current line
const previousLinesHeight = document.querySelectorAll('.line')[1].offsetHeight;
contentElement.style.top = `-${previousLinesHeight}px`;
});
</script>
</body>
</html>