// Main Image Magnifier Class class ImageMagnifier { constructor(containerId, previewId, options = {}) { this.container = document.getElementById(containerId); this.preview = document.getElementById(previewId); this.img = this.container.querySelector('img'); this.lens = document.getElementById('lens'); this.zoom = options.zoom || 2; this.lensSize = options.lensSize || 150; this.init(); } init() { if (this.img.complete) { this.setupMagnifier(); } else { this.img.addEventListener('load', () => this.setupMagnifier()); } } setupMagnifier() { // Update preview background this.updatePreviewBackground(); // Mouse events this.container.addEventListener('mouseenter', () => this.showMagnifier()); this.container.addEventListener('mouseleave', () => this.hideMagnifier()); this.container.addEventListener('mousemove', (e) => this.moveMagnifier(e)); // Touch events for mobile this.container.addEventListener('touchstart', (e) => { e.preventDefault(); this.showMagnifier(); this.moveMagnifier(e.touches[0]); }); this.container.addEventListener('touchmove', (e) => { e.preventDefault(); this.moveMagnifier(e.touches[0]); }); this.container.addEventListener('touchend', () => this.hideMagnifier()); } updatePreviewBackground() { this.preview.style.backgroundImage = `url('${this.img.src}')`; this.preview.style.backgroundSize = `${this.img.width * this.zoom}px ${this.img.height * this.zoom}px`; } showMagnifier() { this.lens.style.opacity = '1'; this.lens.classList.add('active'); this.preview.classList.add('active'); // Clear the placeholder content const placeholder = this.preview.querySelector('.absolute'); if (placeholder) placeholder.style.display = 'none'; } hideMagnifier() { this.lens.style.opacity = '0'; this.lens.classList.remove('active'); this.preview.classList.remove('active'); } moveMagnifier(e) { const rect = this.img.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; let lensX = x - (this.lensSize / 2); let lensY = y - (this.lensSize / 2); // Boundary checks lensX = Math.max(0, Math.min(lensX, this.img.width - this.lensSize)); lensY = Math.max(0, Math.min(lensY, this.img.height - this.lensSize)); // Position lens this.lens.style.left = `${lensX}px`; this.lens.style.top = `${lensY}px`; this.lens.style.width = `${this.lensSize}px`; this.lens.style.height = `${this.lensSize}px`; // Calculate background position for preview const bgX = (lensX / this.img.width) * 100; const bgY = (lensY / this.img.height) * 100; this.preview.style.backgroundPosition = `${bgX}% ${bgY}%`; } updateZoom(newZoom) { this.zoom = newZoom; this.updatePreviewBackground(); } updateLensSize(newSize) { this.lensSize = newSize; } changeImage(newSrc) { this.img.src = newSrc; this.img.onload = () => { this.updatePreviewBackground(); }; } } // Inline Magnifier class InlineMagnifier { constructor() { this.container = document.getElementById('inline-magnifier'); this.img = this.container.querySelector('img'); this.lens = document.getElementById('inline-lens'); this.zoom = 2; this.init(); } init() { this.lens.style.backgroundImage = `url('${this.img.src}')`; this.lens.style.backgroundSize = `${this.img.width * this.zoom}px ${this.img.height * this.zoom}px`; this.container.addEventListener('mouseenter', () => this.lens.style.opacity = '1'); this.container.addEventListener('mouseleave', () => this.lens.style.opacity = '0'); this.container.addEventListener('mousemove', (e) => this.moveLens(e)); } moveLens(e) { const rect = this.img.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const lensWidth = 200; const lensHeight = 200; let lensX = x - (lensWidth / 2); let lensY = y - (lensHeight / 2); lensX = Math.max(0, Math.min(lensX, this.img.width - lensWidth)); lensY = Math.max(0, Math.min(lensY, this.img.height - lensHeight)); this.lens.style.left = `${lensX}px`; this.lens.style.top = `${lensY}px`; const bgX = (lensX / this.img.width) * 100; const bgY = (lensY / this.img.height) * 100; this.lens.style.backgroundPosition = `${bgX}% ${bgY}%`; } } // Corner Magnifier class CornerMagnifier { constructor() { this.container = document.getElementById('corner-magnifier'); this.img = this.container.querySelector('img'); this.zoom = document.getElementById('corner-zoom'); this.content = document.getElementById('corner-zoom-content'); this.zoomLevel = 3; this.init(); } init() { this.content.style.backgroundImage = `url('${this.img.src}')`; this.content.style.backgroundSize = `${this.img.width * this.zoomLevel}px ${this.img.height * this.zoomLevel}px`; this.container.addEventListener('mouseenter', () => this.zoom.style.opacity = '1'); this.container.addEventListener('mouseleave', () => this.zoom.style.opacity = '0'); this.container.addEventListener('mousemove', (e) => this.updateZoom(e)); } updateZoom(e) { const rect = this.img.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const bgX = (x / this.img.width) * 100; const bgY = (y / this.img.height) * 100; this.content.style.backgroundPosition = `${bgX}% ${bgY}%`; } } // Glass Magnifier class GlassMagnifier { constructor() { this.container = document.getElementById('glass-magnifier'); this.img = this.container.querySelector('img'); this.lens = document.getElementById('glass-lens'); this.zoom = 2.5; this.init(); } init() { this.lens.style.backgroundImage = `url('${this.img.src}')`; this.lens.style.backgroundSize = `${this.img.width * this.zoom}px ${this.img.height * this.zoom}px`; this.container.addEventListener('mouseenter', () => this.lens.style.opacity = '1'); this.container.addEventListener('mouseleave', () => this.lens.style.opacity = '0'); this.container.addEventListener('mousemove', (e) => this.moveLens(e)); } moveLens(e) { const rect = this.img.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; const lensSize = 120; let lensX = x - (lensSize / 2); let lensY = y - (lensSize / 2); lensX = Math.max(0, Math.min(lensX, this.img.width - lensSize)); lensY = Math.max(0, Math.min(lensY, this.img.height - lensSize)); this.lens.style.left = `${lensX}px`; this.lens.style.top = `${lensY}px`; const bgX = (lensX / this.img.width) * 100; const bgY = (lensY / this.img.height) * 100; this.lens.style.backgroundPosition = `${bgX}% ${bgY}%`; } } // Initialize all magnifiers when DOM is loaded document.addEventListener('DOMContentLoaded', () => { // Main magnifier const mainMagnifier = new ImageMagnifier('magnifier-container', 'zoom-preview'); // Zoom controls const zoomSlider = document.getElementById('zoom-slider'); const zoomValue = document.getElementById('zoom-value'); const lensSizeSlider = document.getElementById('lens-size'); const lensSizeValue = document.getElementById('lens-size-value'); zoomSlider.addEventListener('input', (e) => { const value = e.target.value; zoomValue.textContent = `${value}x`; mainMagnifier.updateZoom(parseFloat(value)); }); lensSizeSlider.addEventListener('input', (e) => { const value = e.target.value; lensSizeValue.textContent = `${value}px`; mainMagnifier.updateLensSize(parseInt(value)); }); // Thumbnail switching const thumbnails = document.querySelectorAll('.thumbnail-card'); thumbnails.forEach(thumb => { thumb.addEventListener('click', () => { // Remove active class from all thumbnails thumbnails.forEach(t => { t.classList.remove('active'); t.classList.remove('border-purple-500'); t.classList.add('border-gray-200'); }); // Add active class to clicked thumbnail thumb.classList.add('active'); thumb.classList.remove('border-gray-200'); thumb.classList.add('border-purple-500'); // Change main image const imageSrc = thumb.dataset.image; mainMagnifier.changeImage(imageSrc); }); }); // Initialize alternative magnifiers new InlineMagnifier(); new CornerMagnifier(); new GlassMagnifier(); });