Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>PDF Reader</title> | |
| <script src="https://cdn.jsdelivr.net/npm/[email protected]/build/pdf.min.js"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; | |
| background-color: #f8f9fa; | |
| color: #333; | |
| line-height: 1.6; | |
| } | |
| .header { | |
| background-color: #2c3e50; | |
| color: white; | |
| padding: 1rem 2rem; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); | |
| } | |
| .logo { | |
| display: flex; | |
| align-items: center; | |
| gap: 0.5rem; | |
| text-decoration: none; | |
| color: white; | |
| font-weight: 600; | |
| font-size: 1.1rem; | |
| } | |
| .logo i { | |
| font-size: 1.3rem; | |
| } | |
| .nav-links { | |
| display: flex; | |
| gap: 1.5rem; | |
| align-items: center; | |
| } | |
| .nav-links a { | |
| color: white; | |
| text-decoration: none; | |
| font-weight: 500; | |
| transition: opacity 0.2s; | |
| } | |
| .nav-links a:hover { | |
| opacity: 0.8; | |
| } | |
| .nav-links .btn { | |
| background-color: #3498db; | |
| padding: 0.5rem 1rem; | |
| border-radius: 4px; | |
| transition: background-color 0.2s; | |
| } | |
| .nav-links .btn:hover { | |
| background-color: #2980b9; | |
| } | |
| .main-content { | |
| padding: 2rem; | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| } | |
| .pdf-container { | |
| background-color: white; | |
| border-radius: 8px; | |
| box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); | |
| overflow: hidden; | |
| margin-bottom: 2rem; | |
| } | |
| .pdf-viewer { | |
| width: 100%; | |
| height: 80vh; | |
| overflow: auto; | |
| background-color: #f5f5f5; | |
| position: relative; | |
| } | |
| .pdf-page { | |
| width: 100%; | |
| margin-bottom: 1rem; | |
| box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); | |
| background-color: white; | |
| } | |
| .pdf-page img { | |
| width: 100%; | |
| display: block; | |
| } | |
| .loading { | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| height: 100%; | |
| font-size: 1.2rem; | |
| color: #666; | |
| } | |
| .controls { | |
| display: flex; | |
| justify-content: center; | |
| gap: 1rem; | |
| margin: 1rem 0; | |
| flex-wrap: wrap; | |
| } | |
| .controls button { | |
| background-color: #3498db; | |
| color: white; | |
| border: none; | |
| padding: 0.5rem 1rem; | |
| border-radius: 4px; | |
| cursor: pointer; | |
| font-weight: 500; | |
| transition: background-color 0.2s; | |
| } | |
| .controls button:hover { | |
| background-color: #2980b9; | |
| } | |
| .controls button:disabled { | |
| background-color: #95a5a6; | |
| cursor: not-allowed; | |
| } | |
| .footer { | |
| background-color: #2c3e50; | |
| color: white; | |
| text-align: center; | |
| padding: 1.5rem; | |
| margin-top: 2rem; | |
| } | |
| .footer-content { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| flex-wrap: wrap; | |
| gap: 1rem; | |
| } | |
| .footer-links { | |
| display: flex; | |
| gap: 1rem; | |
| } | |
| .footer-links a { | |
| color: white; | |
| text-decoration: none; | |
| opacity: 0.8; | |
| transition: opacity 0.2s; | |
| } | |
| .footer-links a:hover { | |
| opacity: 1; | |
| } | |
| .anycoder-link { | |
| color: #3498db; | |
| text-decoration: none; | |
| font-weight: 500; | |
| } | |
| .anycoder-link:hover { | |
| text-decoration: underline; | |
| } | |
| @media (max-width: 768px) { | |
| .header { | |
| flex-direction: column; | |
| gap: 1rem; | |
| padding: 1rem; | |
| } | |
| .nav-links { | |
| flex-wrap: wrap; | |
| justify-content: center; | |
| gap: 1rem; | |
| } | |
| .main-content { | |
| padding: 1rem; | |
| } | |
| .pdf-viewer { | |
| height: 70vh; | |
| } | |
| .footer-content { | |
| flex-direction: column; | |
| text-align: center; | |
| } | |
| } | |
| @media (max-width: 480px) { | |
| .header { | |
| padding: 0.75rem; | |
| } | |
| .nav-links { | |
| gap: 0.75rem; | |
| } | |
| .controls { | |
| gap: 0.5rem; | |
| } | |
| .controls button { | |
| padding: 0.4rem 0.8rem; | |
| font-size: 0.9rem; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header class="header"> | |
| <a href="#" class="logo"> | |
| <i class="fas fa-file-pdf"></i> | |
| <span>PDF Reader</span> | |
| </a> | |
| <nav class="nav-links"> | |
| <a href="#">Home</a> | |
| <a href="#">About</a> | |
| <a href="#" class="btn">Contact</a> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" class="anycoder-link" target="_blank">Built with anycoder</a> | |
| </nav> | |
| </header> | |
| <main class="main-content"> | |
| <div class="pdf-container"> | |
| <div class="pdf-viewer" id="pdfViewer"> | |
| <div class="loading">Loading PDF...</div> | |
| </div> | |
| <div class="controls"> | |
| <button id="prevPage" disabled>Previous</button> | |
| <span id="pageInfo">Page 1</span> | |
| <button id="nextPage">Next</button> | |
| </div> | |
| </div> | |
| </main> | |
| <footer class="footer"> | |
| <div class="footer-content"> | |
| <div> | |
| <p>© 2024 PDF Reader. All rights reserved.</p> | |
| </div> | |
| <div class="footer-links"> | |
| <a href="#">Privacy Policy</a> | |
| <a href="#">Terms of Service</a> | |
| <a href="#">Contact</a> | |
| </div> | |
| </div> | |
| </footer> | |
| <script> | |
| // Initialize PDF.js | |
| pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.jsdelivr.net/npm/[email protected]/build/pdf.worker.min.js'; | |
| // PDF URL | |
| const pdfUrl = 'https://cdn.openai.com/pdf/3a4153c8-c748-4b71-8e31-aecbde944f8d/oai_5_2_system-card.pdf'; | |
| // DOM elements | |
| const pdfViewer = document.getElementById('pdfViewer'); | |
| const prevPageBtn = document.getElementById('prevPage'); | |
| const nextPageBtn = document.getElementById('nextPage'); | |
| const pageInfo = document.getElementById('pageInfo'); | |
| // PDF variables | |
| let pdfDoc = null; | |
| let pageNum = 1; | |
| let pageRendering = false; | |
| let pageNumPending = null; | |
| let scale = 1.5; | |
| let canvas = null; | |
| let ctx = null; | |
| // Load the PDF document | |
| pdfjsLib.getDocument(pdfUrl).promise.then(function(pdf) { | |
| pdfDoc = pdf; | |
| document.querySelector('.loading').style.display = 'none'; | |
| renderPage(pageNum); | |
| updatePageInfo(); | |
| }).catch(function(error) { | |
| document.querySelector('.loading').textContent = 'Error loading PDF: ' + error.message; | |
| }); | |
| // Render a specific page | |
| function renderPage(num) { | |
| pageRendering = true; | |
| pdfDoc.getPage(num).then(function(page) { | |
| // Create canvas if it doesn't exist | |
| if (!canvas) { | |
| canvas = document.createElement('canvas'); | |
| ctx = canvas.getContext('2d'); | |
| pdfViewer.appendChild(canvas); | |
| } | |
| const viewport = page.getViewport({ scale: scale }); | |
| canvas.height = viewport.height; | |
| canvas.width = viewport.width; | |
| // Render PDF page into canvas context | |
| const renderContext = { | |
| canvasContext: ctx, | |
| viewport: viewport | |
| }; | |
| const renderTask = page.render(renderContext); | |
| renderTask.promise.then(function() { | |
| pageRendering = false; | |
| if (pageNumPending !== null) { | |
| renderPage(pageNumPending); | |
| pageNumPending = null; | |
| } | |
| }); | |
| }); | |
| } | |
| // Go to previous page | |
| prevPageBtn.addEventListener('click', function() { | |
| if (pageNum <= 1) return; | |
| pageNum--; | |
| queueRenderPage(pageNum); | |
| updatePageInfo(); | |
| }); | |
| // Go to next page | |
| nextPageBtn.addEventListener('click', function() { | |
| if (pageNum >= pdfDoc.numPages) return; | |
| pageNum++; | |
| queueRenderPage(pageNum); | |
| updatePageInfo(); | |
| }); | |
| // Queue page rendering | |
| function queueRenderPage(num) { | |
| if (pageRendering) { | |
| pageNumPending = num; | |
| } else { | |
| renderPage(num); | |
| } | |
| } | |
| // Update page info display | |
| function updatePageInfo() { | |
| pageInfo.textContent = `Page ${pageNum} of ${pdfDoc ? pdfDoc.numPages : '?'}`; | |
| prevPageBtn.disabled = pageNum <= 1; | |
| nextPageBtn.disabled = pageNum >= (pdfDoc ? pdfDoc.numPages : 1); | |
| } | |
| // Keyboard navigation | |
| document.addEventListener('keydown', function(e) { | |
| if (e.key === 'ArrowLeft' && pageNum > 1) { | |
| pageNum--; | |
| queueRenderPage(pageNum); | |
| updatePageInfo(); | |
| } else if (e.key === 'ArrowRight' && pageNum < (pdfDoc ? pdfDoc.numPages : 1)) { | |
| pageNum++; | |
| queueRenderPage(pageNum); | |
| updatePageInfo(); | |
| } | |
| }); | |
| // Make the PDF viewer responsive | |
| function handleResize() { | |
| if (pdfDoc) { | |
| renderPage(pageNum); | |
| } | |
| } | |
| window.addEventListener('resize', handleResize); | |
| </script> | |
| </body> | |
| </html> |