zoom-master-pro / script.js
eubottura's picture
[
be997d9 verified
// 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();
});