screen_agent / index.html
eaglelandsonce's picture
Update index.html
b950d11 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PDF Slide Viewer</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.min.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
font-family: Arial, sans-serif;
background-color: #000;
color: #fff;
position: relative;
}
canvas {
display: block;
margin: 0 auto;
width: 100vw;
height: 100vh;
object-fit: contain;
cursor: crosshair;
}
.arrow-button {
position: absolute;
top: 50%;
transform: translateY(-50%);
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
border: none;
font-size: 24px;
padding: 10px;
cursor: pointer;
z-index: 10;
}
.arrow-button:disabled {
cursor: not-allowed;
background-color: rgba(100, 100, 100, 0.5);
}
#prev-slide {
left: 10px;
}
#next-slide {
right: 10px;
}
.links-container {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
}
.link-button {
padding: 10px 15px;
background-color: #1a73e8;
color: #fff;
text-decoration: none;
font-size: 14px;
border-radius: 5px;
border: none;
cursor: pointer;
}
.link-button:hover {
background-color: #1558b8;
}
.toolbar {
position: absolute;
top: 20px;
left: 10px;
z-index: 10;
display: flex;
flex-direction: column;
gap: 10px;
}
.toolbar button {
width: 30px;
height: 30px;
font-size: 16px;
cursor: pointer;
border: none;
border-radius: 50%;
background-color: #444;
color: #fff;
text-align: center;
}
.toolbar button.active {
background-color: #1a73e8;
}
.color-button {
width: 30px;
height: 30px;
border-radius: 50%;
border: 2px solid #fff;
cursor: pointer;
}
.color-button.red {
background-color: red;
}
.color-button.green {
background-color: green;
}
.color-button.blue {
background-color: blue;
}
.color-button.yellow {
background-color: yellow;
}
.slider-container {
position: absolute;
bottom: 20px;
left: 10px;
display: flex;
flex-direction: column;
align-items: center;
z-index: 10;
}
#page-slider {
width: 200px;
}
#page-number-input {
margin-top: 10px;
width: 60px;
text-align: center;
font-size: 16px;
}
.flash-message {
position: absolute;
top: 10px;
left: 50%;
transform: translateX(-50%);
background-color: red;
color: white;
padding: 5px 10px;
border-radius: 5px;
font-size: 14px;
display: none;
z-index: 10;
}
/* Add styles for full-screen button */
#fullscreen-btn {
position: absolute;
top: 20px;
right: 10px;
z-index: 10;
background-color: #444;
color: #fff;
border: none;
font-size: 16px;
padding: 10px;
cursor: pointer;
border-radius: 5px;
}
#fullscreen-btn:hover {
background-color: #1a73e8;
}
</style>
</head>
<body>
<canvas id="pdf-canvas"></canvas>
<button id="prev-slide" class="arrow-button">&#8249;</button>
<button id="next-slide" class="arrow-button">&#8250;</button>
<div id="links-container" class="links-container"></div>
<div class="toolbar">
<button id="toggle-draw" class="color-button">D</button>
<button id="clear-draw" class="color-button">E</button>
<button class="color-button red" data-color="red"></button>
<button class="color-button green" data-color="green"></button>
<button class="color-button blue" data-color="blue"></button>
<button class="color-button yellow" data-color="yellow"></button>
</div>
<div class="slider-container">
<input type="range" id="page-slider" min="1" max="1" value="1">
<input type="number" id="page-number-input" min="1" value="1">
</div>
<div id="flash-message" class="flash-message">Invalid Page Number!</div>
<button id="fullscreen-btn">Full Screen</button>
<script>
const pdfUrl = 'mypdf.pdf'; // Replace with the path to your PDF file
const pdfCanvas = document.getElementById('pdf-canvas');
const ctx = pdfCanvas.getContext('2d');
const prevSlideBtn = document.getElementById('prev-slide');
const nextSlideBtn = document.getElementById('next-slide');
const linksContainer = document.getElementById('links-container');
const toggleDrawBtn = document.getElementById('toggle-draw');
const clearDrawBtn = document.getElementById('clear-draw');
const colorButtons = document.querySelectorAll('.color-button');
const pageSlider = document.getElementById('page-slider');
const pageNumberInput = document.getElementById('page-number-input');
const flashMessage = document.getElementById('flash-message');
// Get the toolbar (drawing tools) element for toggling visibility
const toolbar = document.querySelector('.toolbar');
let pdfDoc = null;
let currentPage = 1;
let totalPages = 0;
let isDrawing = false;
let drawMode = false;
let drawColor = 'red'; // Default drawing color
function clearLinks() {
linksContainer.innerHTML = '';
}
async function renderPage(pageNumber) {
const page = await pdfDoc.getPage(pageNumber);
const viewport = page.getViewport({ scale: 2 });
pdfCanvas.width = viewport.width;
pdfCanvas.height = viewport.height;
const renderContext = {
canvasContext: ctx,
viewport: viewport,
enableWebGL: true
};
ctx.clearRect(0, 0, pdfCanvas.width, pdfCanvas.height);
clearLinks();
await page.render(renderContext).promise;
const annotations = await page.getAnnotations();
annotations.forEach(annotation => {
if (annotation.url) {
const linkButton = document.createElement('a');
linkButton.href = annotation.url;
linkButton.target = '_blank';
linkButton.className = 'link-button';
linkButton.textContent = annotation.title || annotation.url;
linksContainer.appendChild(linkButton);
}
});
prevSlideBtn.disabled = currentPage === 1;
nextSlideBtn.disabled = currentPage === totalPages;
}
async function loadPdf() {
pdfDoc = await pdfjsLib.getDocument(pdfUrl).promise;
totalPages = pdfDoc.numPages;
pageSlider.max = totalPages;
renderPage(currentPage);
}
function showFlashMessage() {
flashMessage.style.display = 'block';
setTimeout(() => {
flashMessage.style.display = 'none';
}, 2000);
}
// Keyboard events
document.addEventListener('keydown', (event) => {
switch (event.key) {
case 'ArrowLeft':
if (currentPage > 1) {
currentPage--;
pageSlider.value = currentPage;
pageNumberInput.value = currentPage;
renderPage(currentPage);
}
break;
case 'ArrowRight':
if (currentPage < totalPages) {
currentPage++;
pageSlider.value = currentPage;
pageNumberInput.value = currentPage;
renderPage(currentPage);
}
break;
case 'd':
drawMode = true;
toggleDrawBtn.classList.add('active');
break;
case 's':
drawMode = false;
toggleDrawBtn.classList.remove('active');
break;
case 'e':
ctx.clearRect(0, 0, pdfCanvas.width, pdfCanvas.height);
renderPage(currentPage);
break;
case 'r':
drawColor = 'red';
break;
case 'g':
drawColor = 'green';
break;
case 'b':
drawColor = 'blue';
break;
case 'y':
drawColor = 'yellow';
break;
case 'h':
// Toggle the display of the toolbar (drawing tools)
if (toolbar.style.display === 'none') {
toolbar.style.display = 'flex';
} else {
toolbar.style.display = 'none';
}
break;
}
});
// Arrow button click events to change slides
prevSlideBtn.addEventListener('click', () => {
if (currentPage > 1) {
currentPage--;
pageSlider.value = currentPage;
pageNumberInput.value = currentPage;
renderPage(currentPage);
}
});
nextSlideBtn.addEventListener('click', () => {
if (currentPage < totalPages) {
currentPage++;
pageSlider.value = currentPage;
pageNumberInput.value = currentPage;
renderPage(currentPage);
}
});
// Slider and number input events
pageSlider.addEventListener('input', (event) => {
currentPage = parseInt(event.target.value);
pageNumberInput.value = currentPage;
renderPage(currentPage);
});
pageNumberInput.addEventListener('change', (event) => {
const page = parseInt(event.target.value);
if (page >= 1 && page <= totalPages) {
currentPage = page;
pageSlider.value = currentPage;
renderPage(currentPage);
} else {
showFlashMessage();
}
});
// ---- CHANGES START HERE: Scale mouse coordinates to match canvas's internal dimensions ----
pdfCanvas.addEventListener('mousedown', (e) => {
if (!drawMode) return;
isDrawing = true;
const rect = pdfCanvas.getBoundingClientRect();
const scaleX = pdfCanvas.width / rect.width;
const scaleY = pdfCanvas.height / rect.height;
const x = (e.clientX - rect.left) * scaleX;
const y = (e.clientY - rect.top) * scaleY;
ctx.beginPath();
ctx.moveTo(x, y);
});
pdfCanvas.addEventListener('mousemove', (e) => {
if (!isDrawing || !drawMode) return;
const rect = pdfCanvas.getBoundingClientRect();
const scaleX = pdfCanvas.width / rect.width;
const scaleY = pdfCanvas.height / rect.height;
const x = (e.clientX - rect.left) * scaleX;
const y = (e.clientY - rect.top) * scaleY;
ctx.lineTo(x, y);
ctx.strokeStyle = drawColor;
ctx.lineWidth = 2;
ctx.stroke();
});
pdfCanvas.addEventListener('mouseup', () => {
if (!drawMode) return;
isDrawing = false;
ctx.closePath();
});
// ---- CHANGES END HERE ----
loadPdf().catch(error => {
console.error('Error loading PDF:', error);
alert('Failed to load PDF. Please check the file path.');
});
// Fullscreen functionality
document.getElementById('fullscreen-btn').addEventListener('click', () => {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
}
}
});
</script>
</body>
</html>