Spaces:
Running
Running
<html lang="ro"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Cititor</title> | |
<style> | |
body { | |
margin: 0; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
height: 100vh; | |
background-color: #f5f5f5; | |
overflow: hidden; | |
} | |
#reader-container { | |
position: relative; | |
width: 100%; | |
height: 100%; | |
overflow: hidden; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
} | |
#reader-container img { | |
width: 100%; | |
height: auto; | |
transform-origin: center center; | |
transition: transform 0.3s; | |
cursor: grab; | |
} | |
@media (min-width: 768px) { | |
#reader-container img { | |
height: 90vh; | |
width: auto; | |
} | |
} | |
.controls { | |
position: absolute; | |
bottom: 20px; | |
display: flex; | |
justify-content: center; | |
gap: 10px; | |
} | |
button { | |
padding: 10px 20px; | |
font-size: 16px; | |
cursor: pointer; | |
border: none; | |
border-radius: 5px; | |
background-color: #007bff; | |
color: white; | |
transition: background-color 0.3s; | |
} | |
button:disabled { | |
background-color: #ddd; | |
cursor: not-allowed; | |
} | |
button:hover:not(:disabled) { | |
background-color: #0056b3; | |
} | |
#page-input { | |
position: absolute; | |
top: 20px; | |
font-size: 24px; | |
padding: 10px 20px; | |
border: none; | |
border-radius: 10px; | |
text-align: center; | |
z-index: 1; | |
width: 190px; | |
@media (orientation: portrait) { | |
transform: translate(30px, 0px); | |
} | |
} | |
#page-input:focus { | |
outline: none; | |
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); | |
} | |
#page-number { | |
position: absolute; | |
top: 20px; | |
left: 20px; | |
font-size: 24px; | |
padding: 10px 20px; | |
border: none; | |
border-radius: 10px; | |
text-align: center; | |
z-index: 1; | |
background-color: #007bff; | |
color: white; | |
} | |
#loading-message { | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
transform: translate(-50%, -50%); | |
font-size: 24px; | |
color: #333; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="reader-container"> | |
<div id="page-number"></div> | |
<input id="page-input" type="number" placeholder="Introdu pagina" oninput="handlePageInput(this.value)"> | |
<img id="page-image" src="pages/1.jpg" alt="Pagina 1" style="display: none;"> | |
<div id="loading-message">Imaginea se încarcă, vă rog așteptați</div> | |
</div> | |
<div class="controls"> | |
<button id="prev-button" disabled>Înapoi</button> | |
<button id="next-button">Înainte</button> | |
</div> | |
<script> | |
const TOTAL_PAGES = 92; | |
let currentPage = 1; | |
const imageElement = document.getElementById('page-image'); | |
const prevButton = document.getElementById('prev-button'); | |
const nextButton = document.getElementById('next-button'); | |
const pageNumberElement = document.getElementById('page-number'); | |
const loadingMessage = document.getElementById('loading-message'); | |
const updatePage = () => { | |
imageElement.src = `pages/${currentPage}.jpg`; | |
imageElement.alt = `Pagina ${currentPage}`; | |
prevButton.disabled = currentPage === 1; | |
nextButton.disabled = currentPage === TOTAL_PAGES; | |
const pageNumber = currentPage * 2 + 1; | |
pageNumberElement.textContent = `${pageNumber - 1}-${pageNumber}`; | |
imageElement.style.display = 'none'; | |
loadingMessage.style.display = 'block'; | |
}; | |
imageElement.onload = () => { | |
imageElement.style.display = 'block'; | |
loadingMessage.style.display = 'none'; | |
}; | |
prevButton.addEventListener('click', () => { | |
if (currentPage > 1) { | |
currentPage--; | |
updatePage(); | |
} | |
}); | |
nextButton.addEventListener('click', () => { | |
if (currentPage < TOTAL_PAGES) { | |
currentPage++; | |
updatePage(); | |
} | |
}); | |
let scale = 1; | |
const zoomStep = 0.1; | |
const maxScale = 3; | |
const minScale = 1; | |
let translateX = 0; | |
let translateY = 0; | |
const zoom = (delta) => { | |
scale = Math.min(maxScale, Math.max(minScale, scale + delta)); | |
applyTransform(); | |
}; | |
const applyTransform = () => { | |
imageElement.style.transform = `scale(${scale}) translate(${translateX}px, ${translateY}px)`; | |
}; | |
imageElement.addEventListener('wheel', (e) => { | |
e.preventDefault(); | |
zoom(e.deltaY < 0 ? zoomStep : -zoomStep); | |
}); | |
let startX = 0; | |
let startY = 0; | |
let isDragging = false; | |
imageElement.addEventListener('mousedown', (e) => { | |
e.preventDefault(); | |
startX = e.clientX; | |
startY = e.clientY; | |
isDragging = true; | |
imageElement.style.cursor = 'grabbing'; | |
}); | |
window.addEventListener('mousemove', (e) => { | |
if (isDragging) { | |
const dx = e.clientX - startX; | |
const dy = e.clientY - startY; | |
translateX += dx / scale; | |
translateY += dy / scale; | |
startX = e.clientX; | |
startY = e.clientY; | |
applyTransform(); | |
} | |
}); | |
window.addEventListener('mouseup', () => { | |
isDragging = false; | |
imageElement.style.cursor = 'grab'; | |
}); | |
let touchStartDistance = 0; | |
imageElement.addEventListener('touchstart', (e) => { | |
if (e.touches.length === 2) { | |
e.preventDefault(); | |
touchStartDistance = Math.hypot( | |
e.touches[0].clientX - e.touches[1].clientX, | |
e.touches[0].clientY - e.touches[1].clientY | |
); | |
} else if (e.touches.length === 1) { | |
startX = e.touches[0].clientX; | |
startY = e.touches[0].clientY; | |
isDragging = true; | |
} | |
}); | |
imageElement.addEventListener('touchmove', (e) => { | |
if (e.touches.length === 2) { | |
e.preventDefault(); | |
const currentDistance = Math.hypot( | |
e.touches[0].clientX - e.touches[1].clientX, | |
e.touches[0].clientY - e.touches[1].clientY | |
); | |
const delta = (currentDistance - touchStartDistance) / 100; | |
zoom(delta); | |
touchStartDistance = currentDistance; | |
} else if (e.touches.length === 1 && isDragging) { | |
e.preventDefault(); | |
const dx = e.touches[0].clientX - startX; | |
const dy = e.touches[0].clientY - startY; | |
translateX += dx / scale; | |
translateY += dy / scale; | |
startX = e.touches[0].clientX; | |
startY = e.touches[0].clientY; | |
applyTransform(); | |
} | |
}); | |
imageElement.addEventListener('touchend', () => { | |
isDragging = false; | |
}); | |
function handlePageInput(value) { | |
const pageNumber = parseInt(value); | |
if (!isNaN(pageNumber)) { | |
if (pageNumber % 2 === 0) { | |
currentPage = pageNumber / 2; | |
} else { | |
currentPage = (pageNumber - 1) / 2; | |
} | |
updatePage(); | |
} | |
} | |
updatePage(); | |
</script> | |
</body> | |
</html> | |