CompactAI-Papers / reveal.js
CompactAI's picture
Upload 4 files
e933ca7 verified
document.addEventListener('DOMContentLoaded', () => {
const paperBody = document.querySelector('.paper-body');
if (!paperBody) return;
const cursor = document.createElement('div');
cursor.className = 'llm-cursor';
document.body.appendChild(cursor);
function wrapWords(element) {
const nodes = Array.from(element.childNodes);
nodes.forEach(node => {
if (node.nodeType === Node.TEXT_NODE) {
const text = node.textContent;
if (text.trim() === '') return;
const fragment = document.createDocumentFragment();
const words = text.split(/(\s+)/);
words.forEach(word => {
if (word.length === 0) return;
if (word.trim() === '') {
fragment.appendChild(document.createTextNode(word));
} else {
const span = document.createElement('span');
span.className = 'word-wrapper';
span.textContent = word;
fragment.appendChild(span);
}
});
element.replaceChild(fragment, node);
} else if (node.nodeType === Node.ELEMENT_NODE &&
node.tagName !== 'SCRIPT' &&
node.tagName !== 'STYLE' &&
!node.classList.contains('proof-script')) {
wrapWords(node);
}
});
}
wrapWords(paperBody);
const queue = [];
let isProcessing = false;
const containers = Array.from(paperBody.querySelectorAll('p, h1, h2, h3, li, blockquote'));
const revealedContainers = new Set();
// Track active word for cursor repositioning on scroll
let activeWord = null;
function updateCursorPosition() {
if (!activeWord || !cursor.classList.contains('active')) return;
const rect = activeWord.getBoundingClientRect();
cursor.style.position = 'fixed';
cursor.style.left = `${rect.right}px`;
cursor.style.top = `${rect.top}px`;
cursor.style.height = `${rect.height}px`;
cursor.style.width = '2px';
}
function checkVisibility() {
const viewportHeight = window.innerHeight;
containers.forEach(container => {
if (revealedContainers.has(container)) return;
const rect = container.getBoundingClientRect();
if (rect.top < viewportHeight * 0.95) {
revealedContainers.add(container);
queue.push(container);
if (!isProcessing) processQueue();
}
});
// Ensure cursor follows scroll
updateCursorPosition();
}
window.addEventListener('scroll', checkVisibility, { passive: true });
setInterval(checkVisibility, 50); // High frequency check for smoother cursor
checkVisibility();
async function processQueue() {
if (queue.length === 0) {
isProcessing = false;
cursor.classList.remove('active');
activeWord = null;
return;
}
isProcessing = true;
const container = queue.shift();
await revealWordsInContainer(container);
processQueue();
}
function getDynamicDelay() {
const viewportHeight = window.innerHeight;
const hiddenWordsInView = document.querySelectorAll('.word-wrapper:not(.revealed)');
let countInView = 0;
hiddenWordsInView.forEach(word => {
const rect = word.getBoundingClientRect();
if (rect.top < viewportHeight && rect.bottom > 0) countInView++;
});
const minDelay = 4;
const maxDelay = 60;
const scaleFactor = 150;
const ratio = Math.min(countInView / scaleFactor, 1);
return maxDelay - (ratio * (maxDelay - minDelay));
}
async function revealWordsInContainer(container) {
const words = Array.from(container.querySelectorAll('.word-wrapper:not(.revealed)'));
if (words.length === 0) return;
cursor.classList.add('active');
for (const word of words) {
activeWord = word;
word.classList.add('revealing');
updateCursorPosition();
const baseDelay = getDynamicDelay();
const delay = baseDelay + Math.random() * (baseDelay * 0.4);
await new Promise(r => setTimeout(r, delay));
word.classList.add('revealed');
word.classList.remove('revealing');
updateCursorPosition();
}
}
});