Hello fluffy animals on the internet! I added ability to zoom into images on this website! Now you can see every detail in my artworks :3.
How it works:
- Click on any image
- Zoom-in or Zoom-out with scroll-wheel
Script:
document.addEventListener('DOMContentLoaded', function() {
// Create the fullscreen viewer elements
const viewer = document.createElement('div');
viewer.id = 'wp-image-viewer';
viewer.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.9);
display: flex;
justify-content: center;
align-items: center;
z-index: 999999;
opacity: 0;
transition: opacity 0.3s ease;
pointer-events: none;
cursor: zoom-out;
`;
const image = document.createElement('img');
image.style.maxHeight = 'calc(100% - 20px)';
image.style.maxWidth = 'calc(100% - 20px)';
image.style.objectFit = 'contain';
image.style.transform = 'scale(1)';
image.style.cursor = 'zoom-in';
const closeBtn = document.createElement('button');
closeBtn.innerHTML = '×';
closeBtn.style.cssText = `
position: absolute;
top: 20px;
right: 20px;
background: none;
border: none;
color: white;
font-size: 40px;
cursor: pointer;
z-index: 10;
`;
// Zoom controls
const zoomControls = document.createElement('div');
zoomControls.style.cssText = `
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 10px;
z-index: 10;
`;
const zoomInBtn = document.createElement('button');
zoomInBtn.innerHTML = '+';
zoomInBtn.style.cssText = `
background: rgba(255,255,255,0.2);
border: none;
color: white;
font-size: 24px;
width: 40px;
height: 40px;
border-radius: 50%;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
`;
const zoomOutBtn = document.createElement('button');
zoomOutBtn.innerHTML = '−';
zoomOutBtn.style.cssText = zoomInBtn.style.cssText;
const resetZoomBtn = document.createElement('button');
resetZoomBtn.innerHTML = '↺';
resetZoomBtn.style.cssText = zoomInBtn.style.cssText;
zoomControls.appendChild(zoomInBtn);
zoomControls.appendChild(zoomOutBtn);
zoomControls.appendChild(resetZoomBtn);
viewer.appendChild(image);
viewer.appendChild(closeBtn);
viewer.appendChild(zoomControls);
document.body.appendChild(viewer);
// Zoom state
let currentScale = 1;
const minScale = 0.5;
const maxScale = 5;
const zoomStep = 0.2;
let isDragging = false;
let startX = 0;
let startY = 0;
let scrollLeft = 0;
let scrollTop = 0;
// Find all eligible WordPress image containers
const containers = document.querySelectorAll('.wp-block-image, .wp-block-media-text__media');
containers.forEach(container => {
// Recursively find the first image within the container
const img = findFirstImage(container);
if (!img) return;
// Add click handler to the container
container.style.cursor = 'zoom-in';
container.addEventListener('click', function(e) {
// Prevent triggering if clicked on nested links
if (e.target.tagName === 'A') return;
// Set image source and show viewer
image.src = img.currentSrc || img.src;
image.alt = img.alt || '';
showViewer();
});
});
// Viewer control functions
function showViewer() {
currentScale = 1;
image.style.transform = 'scale(1)';
viewer.style.opacity = 1;
viewer.style.pointerEvents = 'all';
document.body.style.overflow = 'hidden';
}
function hideViewer() {
viewer.style.opacity = 0;
viewer.style.pointerEvents = 'none';
document.body.style.overflow = '';
}
// Zoom functions
function zoomImage(scale) {
currentScale = Math.min(maxScale, Math.max(minScale, scale));
image.style.transform = `scale(${currentScale})`;
}
function zoomIn() {
zoomImage(currentScale + zoomStep);
}
function zoomOut() {
zoomImage(currentScale - zoomStep);
}
function resetZoom() {
zoomImage(1);
}
// Panning functionality
image.addEventListener('mousedown', (e) => {
if (currentScale <= 1) return;
isDragging = true;
startX = e.pageX - image.offsetLeft;
startY = e.pageY - image.offsetTop;
scrollLeft = image.scrollLeft;
scrollTop = image.scrollTop;
image.style.cursor = 'grabbing';
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
e.preventDefault();
const x = e.pageX - image.offsetLeft;
const y = e.pageY - image.offsetTop;
const walkX = (x - startX) * 2;
const walkY = (y - startY) * 2;
image.scrollLeft = scrollLeft - walkX;
image.scrollTop = scrollTop - walkY;
});
document.addEventListener('mouseup', () => {
isDragging = false;
image.style.cursor = currentScale > 1 ? 'grab' : 'zoom-in';
});
// Event listeners for viewer
viewer.addEventListener('click', (e) => {
if (e.target === viewer) hideViewer();
});
closeBtn.addEventListener('click', hideViewer);
image.addEventListener('click', (e) => {
if (currentScale > 1) {
// If zoomed, clicking zooms out
resetZoom();
} else {
// If not zoomed, clicking toggles zoom
zoomIn();
}
});
// Mouse wheel zoom
image.addEventListener('wheel', (e) => {
e.preventDefault();
if (e.deltaY < 0) {
// Zoom in when scrolling up
zoomIn();
} else {
// Zoom out when scrolling down
zoomOut();
}
});
// Button events
zoomInBtn.addEventListener('click', zoomIn);
zoomOutBtn.addEventListener('click', zoomOut);
resetZoomBtn.addEventListener('click', resetZoom);
// Close with ESC key
document.addEventListener('keydown', e => {
if (e.key === 'Escape' && viewer.style.opacity === '1') hideViewer();
});
// Recursive function to find first image
function findFirstImage(element) {
if (element.tagName === 'IMG') return element;
const children = element.children;
for (let i = 0; i < children.length; i++) {
const found = findFirstImage(children[i]);
if (found) return found;
}
return null;
}
});
Leave a Reply