luna_ocr / public /index.html
veela4's picture
Add files using upload-large-folder tool
373c769 verified
Raw History Blame Contribute Delete
5.95 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon"
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>πŸŒ™πŸ’›</text></svg>" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#0a0a0f" />
<meta name="description" content="Luna OCR - Advanced Text Extraction from PDFs and Images" />
<title>πŸŒ™πŸ’› Luna OCR - Text Extraction</title>
<!-- Preload fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Martian+Mono:wght@100..800&display=swap" rel="stylesheet">
<!-- Meta tags for better SEO -->
<meta property="og:title" content="Luna OCR - Text Extraction" />
<meta property="og:description"
content="Extract text from PDFs and images using advanced Luna processing. Support for Thai language and structured formatting." />
<meta property="og:type" content="website" />
<meta name="twitter:card" content="summary_large_image" />
<style>
/* Prevent flash of unstyled content */
body {
margin: 0;
background: #141414 !important;
color: #ffffff;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Inter', sans-serif;
overflow: hidden;
}
/* Loading screen styles - applied immediately */
#loading {
position: fixed !important;
top: 0 !important;
left: 0 !important;
width: 100vw !important;
height: 100vh !important;
background: #141414 !important;
z-index: 99999 !important;
display: flex !important;
align-items: center;
justify-content: center;
opacity: 1 !important;
}
/* Hide React root initially */
#root {
opacity: 0;
transition: opacity 0.3s ease;
}
/* Show root when loading is done */
body.loaded #root {
opacity: 1;
}
body.loaded #loading {
display: none !important;
}
</style>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<!-- Loading screen -->
<div id="loading" class="loading-container">
<div class="a-hole">
<canvas class="js-canvas"></canvas>
<div class="aura"></div>
</div>
</div>
<div id="root"></div>
<script>
// Simple loading screen that won't interfere with React
document.addEventListener('DOMContentLoaded', function () {
const canvas = document.querySelector('.js-canvas');
if (!canvas) return;
const ctx = canvas.getContext('2d');
let animationId;
// Set canvas size
function resizeCanvas() {
const rect = canvas.parentElement.getBoundingClientRect();
canvas.width = rect.width;
canvas.height = rect.height;
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
// Optimized particle animation - fewer particles for better performance
const particles = [];
for (let i = 0; i < 25; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
vx: (Math.random() - 0.5) * 1.5,
vy: (Math.random() - 0.5) * 1.5,
size: Math.random() * 2 + 1,
opacity: Math.random() * 0.6 + 0.3
});
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw particles - all visible immediately
particles.forEach(particle => {
particle.x += particle.vx;
particle.y += particle.vy;
// Wrap around edges
if (particle.x < 0) particle.x = canvas.width;
if (particle.x > canvas.width) particle.x = 0;
if (particle.y < 0) particle.y = canvas.height;
if (particle.y > canvas.height) particle.y = 0;
ctx.fillStyle = `rgba(255, 255, 255, ${particle.opacity})`;
ctx.beginPath();
ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
ctx.fill();
});
animationId = requestAnimationFrame(animate);
}
// Start animation after 500ms delay
setTimeout(() => {
animate();
}, 500);
// Hide loading screen when React loads
function hideLoading() {
cancelAnimationFrame(animationId);
document.body.classList.add('loaded');
}
// Fast loading screen removal
let reactLoaded = false;
// Check for actual app content (header with Luna OCR)
const checkReactLoaded = () => {
const root = document.getElementById('root');
const appHeader = root?.querySelector('.app-header');
const logoContent = root?.querySelector('.logo');
if (root && root.children.length > 0 && (appHeader || logoContent) && !reactLoaded) {
reactLoaded = true;
// Small delay to ensure orb and other components are ready
setTimeout(hideLoading, 200);
}
};
// Fast polling every 100ms
const pollInterval = setInterval(() => {
checkReactLoaded();
if (reactLoaded) {
clearInterval(pollInterval);
}
}, 100);
// Much faster fallback - hide after 800ms max
setTimeout(() => {
if (!reactLoaded) {
hideLoading();
}
}, 800);
// Immediate check on DOM ready
if (document.readyState === 'complete') {
setTimeout(checkReactLoaded, 100);
}
});
</script>
</body>
</html>