아래 HTML 소스 코드를 활용하면 상품 상세 대표 이미지에 마우스를 호버할 때 확대 효과를 적용할 수 있어요.
•
데스크톱: 커서가 대표 이미지에 호버되었을 때 작동합니다.
•
모바일: 대표 이미지에 터치하면 터치한 영역이 확대됩니다.
•
코드 상에서 let scaleValue = 2.5; 의 숫자를 조정하여 배율을 변경할 수 있습니다.
Essential 테마
<script>
(() => {
const script = document.createElement("script");
script.innerHTML = `
(() => {
const applyZoomEffect = (image) => {
if (!image) return;
image.removeEventListener("mouseenter", image._mouseenterHandler);
image.removeEventListener("mouseleave", image._mouseleaveHandler);
image.removeEventListener("mousemove", image._mousemoveHandler);
image.removeEventListener("touchstart", image._touchstartHandler);
image.removeEventListener("touchmove", image._touchmoveHandler);
image.removeEventListener("touchend", image._touchendHandler);
let isHovered = false;
let isZoomed = false;
let scaleValue = 2.5; // 이 값은 확대 배율을 조정합니다. 원하는 배율로 변경해 주세요.
let startX = 0, startY = 0, moveX = 0, moveY = 0;
let touchMoved = false;
let isHorizontalSwipe = false;
image.style.transform = "scale(1)";
image.style.transition = "none";
image._mouseenterHandler = () => {
isHovered = true;
image.style.transform = \`scale(\${scaleValue})\`;
image.style.transition = "transform 0.2s ease-out";
};
image._mouseleaveHandler = () => {
isHovered = false;
image.style.transform = "scale(1)";
image.style.transition = "transform 0.1s ease-in-out";
};
image._mousemoveHandler = (e) => {
if (!isHovered) return;
const rect = image.getBoundingClientRect();
const relativeX = ((e.clientX - rect.left) / rect.width * 100).toFixed(2);
const relativeY = ((e.clientY - rect.top) / rect.height * 100).toFixed(2);
image.style.transformOrigin = \`\${relativeX}% \${relativeY}%\`;
};
image._touchstartHandler = (e) => {
e.stopPropagation();
touchMoved = false;
isHorizontalSwipe = false;
startX = e.touches[0].clientX;
startY = e.touches[0].clientY;
};
image._touchmoveHandler = (e) => {
const deltaX = Math.abs(e.touches[0].clientX - startX);
const deltaY = Math.abs(e.touches[0].clientY - startY);
if (deltaX > 10) {
isHorizontalSwipe = true;
}
if (isHorizontalSwipe) {
e.preventDefault();
}
if (deltaX > 10 || deltaY > 10) {
touchMoved = true;
}
};
image._touchendHandler = (e) => {
if (touchMoved) return;
if (isZoomed) {
isZoomed = false;
image.style.transform = "scale(1)";
image.style.transition = "transform 0.1s ease-in-out";
} else {
isZoomed = true;
const rect = image.getBoundingClientRect();
const touchX = e.changedTouches[0].clientX;
const touchY = e.changedTouches[0].clientY;
const relativeX = ((touchX - rect.left) / rect.width * 100).toFixed(2);
const relativeY = ((touchY - rect.top) / rect.height * 100).toFixed(2);
image.style.transformOrigin = \`\${relativeX}% \${relativeY}%\`;
image.style.transform = \`scale(\${scaleValue})\`;
image.style.transition = "transform 0.2s ease-out";
}
};
image.addEventListener("mouseenter", image._mouseenterHandler);
image.addEventListener("mouseleave", image._mouseleaveHandler);
image.addEventListener("mousemove", image._mousemoveHandler);
image.addEventListener("touchstart", image._touchstartHandler);
image.addEventListener("touchmove", image._touchmoveHandler, { passive: false });
image.addEventListener("touchend", image._touchendHandler);
};
const targetImageSelector = "[class*='ProductRequiredInfoThumbnailstyled__ProductRequiredInfoThumbnail'] > :not([class*='ProductRequiredInfoThumbnailstyled__ThumbSwiper']) [class*='ProductImage_image-wrapper'] img";
const initialImageList = document.querySelectorAll(targetImageSelector);
initialImageList.forEach((initialImage) => {
applyZoomEffect(initialImage);
});
const observeMainImage = () => {
let attempts = 0;
const checkImage = setInterval(() => {
const updatedImageList = document.querySelectorAll(targetImageSelector);
if (updatedImageList.length > 0) {
updatedImageList.forEach((updatedImage) => {
applyZoomEffect(updatedImage);
});
clearInterval(checkImage);
}
attempts++;
if (attempts > 50) {
clearInterval(checkImage);
}
}, 15);
};
const observer = new MutationObserver(() => {
observeMainImage();
});
observer.observe(document.body, { childList: true, subtree: true });
})();
`;
document.body.appendChild(script);
})();
</script>
JavaScript
복사
Grid 테마
<script>
(() => {
const script = document.createElement("script");
script.innerHTML = `
(() => {
const applyZoomEffect = (image) => {
if (!image) return;
image.removeEventListener("mouseenter", image._mouseenterHandler);
image.removeEventListener("mouseleave", image._mouseleaveHandler);
image.removeEventListener("mousemove", image._mousemoveHandler);
image.removeEventListener("touchstart", image._touchstartHandler);
image.removeEventListener("touchmove", image._touchmoveHandler);
image.removeEventListener("touchend", image._touchendHandler);
let isHovered = false;
let isZoomed = false;
let scaleValue = 2.5; // 이 값은 확대 배율을 조정합니다. 원하는 배율로 변경해 주세요.
let startX = 0, startY = 0, moveX = 0, moveY = 0;
let touchMoved = false;
let isHorizontalSwipe = false;
image.style.transform = "scale(1)";
image.style.transition = "none";
image._mouseenterHandler = () => {
isHovered = true;
image.style.transform = \`scale(\${scaleValue})\`;
image.style.transition = "transform 0.2s ease-out";
};
image._mouseleaveHandler = () => {
isHovered = false;
image.style.transform = "scale(1)";
image.style.transition = "transform 0.1s ease-in-out";
};
image._mousemoveHandler = (e) => {
if (!isHovered) return;
const rect = image.getBoundingClientRect();
const relativeX = ((e.clientX - rect.left) / rect.width * 100).toFixed(2);
const relativeY = ((e.clientY - rect.top) / rect.height * 100).toFixed(2);
image.style.transformOrigin = \`\${relativeX}% \${relativeY}%\`;
};
image._touchstartHandler = (e) => {
e.stopPropagation();
touchMoved = false;
isHorizontalSwipe = false;
startX = e.touches[0].clientX;
startY = e.touches[0].clientY;
};
image._touchmoveHandler = (e) => {
const deltaX = Math.abs(e.touches[0].clientX - startX);
const deltaY = Math.abs(e.touches[0].clientY - startY);
if (deltaX > 10) {
isHorizontalSwipe = true;
}
if (isHorizontalSwipe) {
e.preventDefault();
}
if (deltaX > 10 || deltaY > 10) {
touchMoved = true;
}
};
image._touchendHandler = (e) => {
if (touchMoved) return;
if (isZoomed) {
isZoomed = false;
image.style.transform = "scale(1)";
image.style.transition = "transform 0.1s ease-in-out";
} else {
isZoomed = true;
const rect = image.getBoundingClientRect();
const touchX = e.changedTouches[0].clientX;
const touchY = e.changedTouches[0].clientY;
const relativeX = ((touchX - rect.left) / rect.width * 100).toFixed(2);
const relativeY = ((touchY - rect.top) / rect.height * 100).toFixed(2);
image.style.transformOrigin = \`\${relativeX}% \${relativeY}%\`;
image.style.transform = \`scale(\${scaleValue})\`;
image.style.transition = "transform 0.2s ease-out";
}
};
image.addEventListener("mouseenter", image._mouseenterHandler);
image.addEventListener("mouseleave", image._mouseleaveHandler);
image.addEventListener("mousemove", image._mousemoveHandler);
image.addEventListener("touchstart", image._touchstartHandler);
image.addEventListener("touchmove", image._touchmoveHandler, { passive: false });
image.addEventListener("touchend", image._touchendHandler);
};
const targetImageSelector = "[class*='ProductRequiredInfo_image-panel__'] img:not([class*='ProductRequiredInfoThumbnail_thumb__M5du1'] img)";
const initialImageList = document.querySelectorAll(targetImageSelector);
initialImageList.forEach((initialImage) => {
applyZoomEffect(initialImage);
});
const observeMainImage = () => {
let attempts = 0;
const checkImage = setInterval(() => {
const updatedImageList = document.querySelectorAll(targetImageSelector);
if (updatedImageList.length > 0) {
updatedImageList.forEach((updatedImage) => {
applyZoomEffect(updatedImage);
});
clearInterval(checkImage);
}
attempts++;
if (attempts > 50) {
clearInterval(checkImage);
}
}, 15);
};
const observer = new MutationObserver(() => {
observeMainImage();
});
observer.observe(document.body, { childList: true, subtree: true });
})();
`;
document.body.appendChild(script);
})();
</script>
JavaScript
복사
Round 테마
<script>
(() => {
const script = document.createElement("script");
script.innerHTML = `
(() => {
const applyZoomEffect = (image) => {
if (!image) return;
image.removeEventListener("mouseenter", image._mouseenterHandler);
image.removeEventListener("mouseleave", image._mouseleaveHandler);
image.removeEventListener("mousemove", image._mousemoveHandler);
image.removeEventListener("touchstart", image._touchstartHandler);
image.removeEventListener("touchmove", image._touchmoveHandler);
image.removeEventListener("touchend", image._touchendHandler);
let isHovered = false;
let isZoomed = false;
let scaleValue = 2.5; // 이 값은 확대 배율을 조정합니다. 원하는 배율로 변경해 주세요.
let startX = 0, startY = 0, moveX = 0, moveY = 0;
let touchMoved = false;
let isHorizontalSwipe = false;
image.style.transform = "scale(1)";
image.style.transition = "none";
image._mouseenterHandler = () => {
isHovered = true;
image.style.transform = \`scale(\${scaleValue})\`;
image.style.transition = "transform 0.2s ease-out";
};
image._mouseleaveHandler = () => {
isHovered = false;
image.style.transform = "scale(1)";
image.style.transition = "transform 0.1s ease-in-out";
};
image._mousemoveHandler = (e) => {
if (!isHovered) return;
const rect = image.getBoundingClientRect();
const relativeX = ((e.clientX - rect.left) / rect.width * 100).toFixed(2);
const relativeY = ((e.clientY - rect.top) / rect.height * 100).toFixed(2);
image.style.transformOrigin = \`\${relativeX}% \${relativeY}%\`;
};
image._touchstartHandler = (e) => {
e.stopPropagation();
touchMoved = false;
isHorizontalSwipe = false;
startX = e.touches[0].clientX;
startY = e.touches[0].clientY;
};
image._touchmoveHandler = (e) => {
const deltaX = Math.abs(e.touches[0].clientX - startX);
const deltaY = Math.abs(e.touches[0].clientY - startY);
if (deltaX > 10) {
isHorizontalSwipe = true;
}
if (isHorizontalSwipe) {
e.preventDefault();
}
if (deltaX > 10 || deltaY > 10) {
touchMoved = true;
}
};
image._touchendHandler = (e) => {
if (touchMoved) return;
if (isZoomed) {
isZoomed = false;
image.style.transform = "scale(1)";
image.style.transition = "transform 0.1s ease-in-out";
} else {
isZoomed = true;
const rect = image.getBoundingClientRect();
const touchX = e.changedTouches[0].clientX;
const touchY = e.changedTouches[0].clientY;
const relativeX = ((touchX - rect.left) / rect.width * 100).toFixed(2);
const relativeY = ((touchY - rect.top) / rect.height * 100).toFixed(2);
image.style.transformOrigin = \`\${relativeX}% \${relativeY}%\`;
image.style.transform = \`scale(\${scaleValue})\`;
image.style.transition = "transform 0.2s ease-out";
}
};
image.addEventListener("mouseenter", image._mouseenterHandler);
image.addEventListener("mouseleave", image._mouseleaveHandler);
image.addEventListener("mousemove", image._mousemoveHandler);
image.addEventListener("touchstart", image._touchstartHandler);
image.addEventListener("touchmove", image._touchmoveHandler, { passive: false });
image.addEventListener("touchend", image._touchendHandler);
};
const targetImageSelector = "[class*='ProductRequiredInfoThumbnail_swiper-item-wrapper__'] img";
const initialImageList = document.querySelectorAll(targetImageSelector);
initialImageList.forEach((initialImage) => {
applyZoomEffect(initialImage);
});
const observeMainImage = () => {
let attempts = 0;
const checkImage = setInterval(() => {
const updatedImageList = document.querySelectorAll(targetImageSelector);
if (updatedImageList.length > 0) {
updatedImageList.forEach((updatedImage) => {
applyZoomEffect(updatedImage);
});
clearInterval(checkImage);
}
attempts++;
if (attempts > 50) {
clearInterval(checkImage);
}
}, 15);
};
const observer = new MutationObserver(() => {
observeMainImage();
});
observer.observe(document.body, { childList: true, subtree: true });
})();
`;
document.body.appendChild(script);
})();
</script>
JavaScript
복사

