You can edit the below JavaScript code to customize the image tool.
Apply Changes
/**
* Creates an interactive image comparison tool.
* It assumes the input image `originalImg` is a composite of two images
* placed side-by-side horizontally. The left half is considered the "before"
* image ("Домик") and the right half is the "after" image ("House").
* The function creates a container with a slider that the user can drag
* to reveal one image over the other.
*
* @param {HTMLImageElement} originalImg The source image object containing two images side-by-side.
* @returns {HTMLElement} A div element containing the interactive image comparison tool.
*/
function processImage(originalImg) {
// Use naturalWidth/Height for images, fallback to width/height for other sources like canvas
const originalWidth = originalImg.naturalWidth || originalImg.width;
const originalHeight = originalImg.naturalHeight || originalImg.height;
// The input image has two images side-by-side. The tool will have the width of one of them.
const comparisonWidth = originalWidth / 2;
const comparisonHeight = originalHeight;
// --- Create DOM Elements ---
// 1. Main container
const container = document.createElement('div');
container.style.position = 'relative';
container.style.width = `${comparisonWidth}px`;
container.style.height = `${comparisonHeight}px`;
container.style.overflow = 'hidden';
container.style.userSelect = 'none'; // Prevent text selection while dragging
container.style.fontFamily = 'Arial, sans-serif';
container.style.border = '1px solid #ccc';
// 2. "Before" (left) image canvas ("Домик")
const leftCanvas = document.createElement('canvas');
leftCanvas.width = comparisonWidth;
leftCanvas.height = comparisonHeight;
const leftCtx = leftCanvas.getContext('2d');
// Draw the left half of the original image
leftCtx.drawImage(originalImg, 0, 0, comparisonWidth, comparisonHeight, 0, 0, comparisonWidth, comparisonHeight);
// 3. "After" (right) image wrapper and canvas ("House")
// This wrapper will be resized to create the reveal effect.
const rightImageWrapper = document.createElement('div');
rightImageWrapper.style.position = 'absolute';
rightImageWrapper.style.top = '0';
rightImageWrapper.style.left = '0';
rightImageWrapper.style.width = `${comparisonWidth / 2}px`; // Start at 50%
rightImageWrapper.style.height = '100%';
rightImageWrapper.style.overflow = 'hidden';
const rightCanvas = document.createElement('canvas');
rightCanvas.width = comparisonWidth;
rightCanvas.height = comparisonHeight;
const rightCtx = rightCanvas.getContext('2d');
// Draw the right half of the original image
rightCtx.drawImage(originalImg, comparisonWidth, 0, comparisonWidth, comparisonHeight, 0, 0, comparisonWidth, comparisonHeight);
rightImageWrapper.appendChild(rightCanvas);
// 4. Slider handle
const slider = document.createElement('div');
slider.style.position = 'absolute';
slider.style.top = '0';
slider.style.left = `${comparisonWidth / 2}px`;
slider.style.width = '4px';
slider.style.height = '100%';
slider.style.backgroundColor = 'rgba(255, 255, 255, 0.9)';
slider.style.cursor = 'ew-resize';
slider.style.transform = 'translateX(-50%)'; // Center line on the coordinate
slider.style.boxShadow = '0px 0px 5px rgba(0,0,0,0.5)';
const sliderHandle = document.createElement('div');
sliderHandle.style.position = 'absolute';
sliderHandle.style.top = '50%';
sliderHandle.style.left = '50%';
sliderHandle.style.width = '40px';
sliderHandle.style.height = '40px';
sliderHandle.style.border = '3px solid rgba(255, 255, 255, 0.9)';
sliderHandle.style.borderRadius = '50%';
sliderHandle.style.transform = 'translate(-50%, -50%)';
sliderHandle.style.backgroundColor = 'rgba(0, 0, 0, 0.2)';
sliderHandle.innerHTML = `
<svg width="100%" height="100%" viewBox="0 0 40 40">
<path d="M15 10 L5 20 L15 30" stroke="white" stroke-width="2.5" fill="none" stroke-linecap="round" />
<path d="M25 10 L35 20 L25 30" stroke="white" stroke-width="2.5" fill="none" stroke-linecap="round" />
</svg>
`;
slider.appendChild(sliderHandle);
// 5. Labels
const createLabel = (text) => {
const label = document.createElement('div');
label.textContent = text;
label.style.position = 'absolute';
label.style.bottom = '15px';
label.style.color = 'white';
label.style.backgroundColor = 'rgba(0, 0, 0, 0.6)';
label.style.padding = '5px 10px';
label.style.borderRadius = '5px';
label.style.pointerEvents = 'none'; // Make sure labels don't interfere with dragging
label.style.textShadow = '1px 1px 2px black';
return label;
};
const leftLabel = createLabel('Домик');
leftLabel.style.left = '15px';
const rightLabel = createLabel('House');
rightLabel.style.right = '15px';
// --- Assemble the Tool ---
// Append in order of z-index (bottom to top)
container.appendChild(leftCanvas);
container.appendChild(rightImageWrapper);
container.appendChild(leftLabel);
container.appendChild(rightLabel);
container.appendChild(slider);
// --- Interaction Logic ---
const moveHandler = (e) => {
e.preventDefault();
const rect = container.getBoundingClientRect();
const x = (e.clientX || e.changedTouches[0].clientX) - rect.left;
// Clamp the slider position within the container bounds
const newX = Math.max(0, Math.min(x, comparisonWidth));
slider.style.left = `${newX}px`;
rightImageWrapper.style.width = `${newX}px`;
};
const stopDragHandler = () => {
// Remove listeners from window to clean up
window.removeEventListener('mousemove', moveHandler);
window.removeEventListener('touchmove', moveHandler);
window.removeEventListener('mouseup', stopDragHandler);
window.removeEventListener('touchend', stopDragHandler);
};
const startDragHandler = (e) => {
e.preventDefault();
// Add move/up listeners to the window so drag works outside the handle
window.addEventListener('mousemove', moveHandler);
window.addEventListener('touchmove', moveHandler);
window.addEventListener('mouseup', stopDragHandler);
window.addEventListener('touchend', stopDragHandler);
};
slider.addEventListener('mousedown', startDragHandler);
slider.addEventListener('touchstart', startDragHandler, { passive: false });
return container;
}
Apply Changes