Created
October 18, 2024 08:40
-
-
Save egeozcan/b27e11a7e776972d18603222fa523ed4 to your computer and use it in GitHub Desktop.
Revisions
-
egeozcan created this gist
Oct 18, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,292 @@ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Fullscreen Image Viewer</title> <style> body { font-family: Arial, sans-serif; } #imageDisplay { max-width: 80%; max-height: 78vh; height: auto; margin: 20px auto; border: 5px dashed #ddd; padding: 10px; cursor: pointer; } .btn { display: inline-block; padding: 10px; background-color: #007bff; color: white; cursor: pointer; margin: 10px; } .btn.danger { background-color: #dc3545; } #buttons { position: sticky; top: 0; display: block; background: white; user-select: none; } #container { width: 80%; margin: auto; text-align: center; } #thumbnails { display: flex; overflow-x: auto; padding: 10px; margin-top: 20px; justify-content: center; } .thumbnail { margin: 0 5px; cursor: pointer; } .thumbnail img { width: 100px; height: auto; border: 2px solid transparent; } .thumbnail img.active { border-color: blue; } [hidden] { display: none !important; } </style> </head> <body> <div id="container"> <div> <input type="file" id="imageInput" multiple accept="image/*" style="display: none;"> <label for="imageInput" class="btn">Select Images</label> </div> <div id="buttons" hidden> <button class="btn" onclick="previousImage()">Previous</button> <button class="btn" onclick="nextImage()">Next</button> <button class="btn danger" onclick="removeCurrentImage()">Remove Current Image</button> </div> <img id="imageDisplay" onclick="toggleFullscreen()"> <div id="imageIndex"></div> <div id="thumbnails"></div> </div> <script> let images = []; let currentIndex = -1; // Start before the first index let touchstartX = 0; let touchendX = 0; function checkSwipeDirection() { if (touchstartX - touchendX > 100) nextImage(); if (touchendX - touchstartX > 100) previousImage(); } document.addEventListener("touchstart", e => { touchstartX = e.changedTouches[0].screenX; }); document.addEventListener("touchend", e => { touchendX = e.changedTouches[0].screenX; checkSwipeDirection(); }); document.getElementById("imageInput").addEventListener("change", handleFiles); document.getElementById("container").addEventListener("paste", handlePaste); document.addEventListener("dragover", preventDefault); document.addEventListener("drop", handleDrop); document.addEventListener("keydown", handleKeydown); function handleFiles(e) { const files = e.target.files; for (let i = 0; i < files.length; i++) { if (files[i].type.startsWith("image/")) { const fileReader = new FileReader(); fileReader.onload = (e) => { images.push(e.target.result); if (i === 0) displayImage(images.length - 1); // Display the last image added addThumbnail(e.target.result, images.length - 1); document.getElementById("buttons").removeAttribute("hidden"); }; fileReader.onerror = (e) => console.log(e.target.error); fileReader.readAsDataURL(files[i]); } } } function handlePaste(e) { const files = e.clipboardData.files; handleFiles({ target: { files } }); } function preventDefault(e) { e.preventDefault(); } function handleDrop(e) { e.preventDefault(); if (!e.dataTransfer) { console.log("DataTransfer is null, this drop event cannot be processed."); return; } const files = e.dataTransfer.files; if (files && files.length > 0) { // Handle files from the user's computer handleFiles({ target: { files } }); } else { // Handle images dragged from other web pages const htmlContent = e.dataTransfer.getData("text/html"); const match = htmlContent && htmlContent.match(/<img [^>]*src="([^"]+)"[^>]*>/i); if (match && match[1]) { images.push(match[1]); displayImage(images.length - 1); // Display the last image added addThumbnail(match[1], images.length - 1); } } } function removeThumbnail(index) { const thumbnailsContainer = document.getElementById("thumbnails"); thumbnailsContainer.removeChild(thumbnailsContainer.children[index]); } function displayImage(index) { const nothingToDisplay = images.length === 0; if (nothingToDisplay) { document.getElementById("buttons").setAttribute("hidden", ""); } else { document.getElementById("buttons").removeAttribute("hidden"); } currentIndex = nothingToDisplay ? -1 : index; document.getElementById("imageDisplay").src = nothingToDisplay ? "" : images[index]; document.getElementById("imageIndex").innerText = nothingToDisplay ? "" : `Image ${index + 1} of ${images.length}`; updateThumbnailActiveState(); } function addThumbnail(imageSrc, index) { const thumbnailWrapper = document.createElement("div"); const thumbnailsContainer = document.getElementById("thumbnails"); thumbnailWrapper.classList.add("thumbnail"); thumbnailWrapper.addEventListener("click", () => displayImage([...thumbnailsContainer.children].indexOf(thumbnailWrapper))); const img = document.createElement("img"); img.src = imageSrc; thumbnailWrapper.appendChild(img); thumbnailsContainer.appendChild(thumbnailWrapper); updateThumbnailActiveState(); } function updateThumbnailActiveState() { const thumbnails = document.querySelectorAll(".thumbnail img"); thumbnails.forEach((img, idx) => { img.classList.remove("active"); if (idx === currentIndex) { img.classList.add("active"); } }); } function nextImage() { if (currentIndex === -1) { return; } displayImage((currentIndex + 1) % images.length); } function previousImage() { if (currentIndex === -1) { return; } displayImage((currentIndex - 1 + images.length) % images.length); } function handleKeydown(e) { if (e.key === "ArrowRight") { nextImage(); } else if (e.key === "ArrowLeft") { previousImage(); } else if (e.key === "Escape") { exitFullscreen(); } else if (e.key === "Delete") { removeCurrentImage(); } else if (e.key === "Enter") { toggleFullscreen(); } } function removeCurrentImage() { if (currentIndex === -1) { return; } images.splice(currentIndex, 1); removeThumbnail(currentIndex); displayImage(currentIndex % images.length); } function toggleFullscreen() { const imgDisplay = document.getElementById("imageDisplay"); if (!document.fullscreenElement) { if (currentIndex === -1) { return; } imgDisplay.requestFullscreen().catch(err => console.log(err)); } else { if (document.exitFullscreen) { document.exitFullscreen(); } } } function exitFullscreen() { if (document.fullscreenElement) { document.exitFullscreen(); } } // load existing images when the page loads from the leftover thumbnails document.addEventListener("DOMContentLoaded", () => { let activeIndex = 0; const thumbnails = document.querySelectorAll(".thumbnail img"); thumbnails.forEach((img, idx) => { images.push(img.src); img.addEventListener("click", () => displayImage(idx)); if (img.classList.contains("active")) { activeIndex = idx; } }); displayImage(activeIndex); }); // change the image when the user uses scroll wheel document.getElementById("imageDisplay").addEventListener("wheel", e => { e.preventDefault(); if (e.deltaY > 0) { nextImage(); } else { previousImage(); } }); </script> </body> </html>