New Page
script.js
Page
1
/
1
100%
document.addEventListener(‘DOMContentLoaded’, function() {
// — App Logic —
const uploadInput = document.getElementById(‘upload-image’);
const dropArea = document.getElementById(‘drop-area’);
const imageContainer = document.getElementById(‘image-container’);
const mainImage = document.getElementById(‘main-image’);
const interactionInstructions = document.getElementById(‘interaction-instructions’);
const actionButtonsContainer = document.getElementById(‘action-buttons-container’);
const downloadBtn = document.getElementById(‘download-btn’);
const changeImageBtn = document.getElementById(‘change-image-btn’);
const controlsWrapper = document.getElementById(‘controls-wrapper’);
const watermark = document.getElementById(‘watermark’);
const watermarkImg = document.getElementById(‘watermark-image’);
const resizeHandle = document.querySelector(‘.resize-handle’);
// Logo Selector
const logoOptions = document.querySelectorAll(‘.logo-option’);
logoOptions.forEach(option => {
option.addEventListener(‘click’, function() {
// Remove selected class from all
logoOptions.forEach(opt => opt.classList.remove(‘selected’));
// Add selected class to clicked
this.classList.add(‘selected’);
// Update watermark image
const newSrc = this.getAttribute(‘data-src’);
watermarkImg.src = newSrc;
});
});
// Social Media Preview
const socialToggle = document.getElementById(‘social-toggle’);
const socialOverlay = document.getElementById(‘social-overlay’);
// State to hold the original image source for high-res export
let originalImageObj = new Image();
let originalFileName = ‘watermarked-image.jpg’;
// Check for Canvas Support
const canvasSupported = !!window.CanvasRenderingContext2D;
if (!canvasSupported) {
alert(‘Your browser does not support high-resolution image processing. Please use a modern browser.’);
}
// Dragging state
let isDragging = false;
let dragStartX, dragStartY;
let initialLeft, initialTop;
// Resizing state
let isResizing = false;
let resizeStartX, resizeStartWidth;
// Toggle Social Overlay
socialToggle.addEventListener(‘change’, function() {
if (this.checked) {
socialOverlay.classList.add(‘active’);
} else {
socialOverlay.classList.remove(‘active’);
}
});
// — File Handling (Drag & Drop + Input) —
// Prevent default drag behaviors for the entire window
// This stops the browser from opening the image if the user misses the drop zone
;[‘dragenter’, ‘dragover’, ‘dragleave’, ‘drop’].forEach(eventName => {
document.body.addEventListener(eventName, preventDefaults, false);
});
// Drag & Drop visual feedback specifically for the drop area
;[‘dragenter’, ‘dragover’, ‘dragleave’, ‘drop’].forEach(eventName => {
dropArea.addEventListener(eventName, preventDefaults, false);
imageContainer.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
;[‘dragenter’, ‘dragover’].forEach(eventName => {
dropArea.addEventListener(eventName, highlightDropArea, false);
imageContainer.addEventListener(eventName, highlightImageContainer, false);
});
;[‘dragleave’, ‘drop’].forEach(eventName => {
dropArea.addEventListener(eventName, unhighlightDropArea, false);
imageContainer.addEventListener(eventName, unhighlightImageContainer, false);
});
function highlightDropArea(e) {
dropArea.classList.add(‘drag-over’);
if (e.dataTransfer) e.dataTransfer.dropEffect = ‘copy’;
}
function unhighlightDropArea(e) {
dropArea.classList.remove(‘drag-over’);
}
function highlightImageContainer(e) {
imageContainer.classList.add(‘drag-over’);
if (e.dataTransfer) e.dataTransfer.dropEffect = ‘copy’;
}
function unhighlightImageContainer(e) {
imageContainer.classList.remove(‘drag-over’);
}
dropArea.addEventListener(‘drop’, handleDrop, false);
imageContainer.addEventListener(‘drop’, handleDrop, false);
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
handleFiles(files);
}
uploadInput.addEventListener(‘change’, function(e) {
handleFiles(e.target.files);
});
changeImageBtn.addEventListener(‘click’, function() {
uploadInput.click();
});
function handleFiles(files) {
const file = files[0];
if (file && file.type.startsWith(‘image/’)) {
originalFileName = file.name.replace(/\.[^/.]+$/, “”) + ‘-watermarked.jpg’;
const reader = new FileReader();
reader.onerror = function() {
alert(‘Error reading file. Please try again.’);
};
reader.onload = function(e) {
originalImageObj.onerror = function() {
alert(‘Error loading image. The file might be corrupted or in an unsupported format.’);
};
originalImageObj.onload = function() {
// Update the UI image
mainImage.src = originalImageObj.src;
// Show UI elements
imageContainer.style.display = ‘inline-block’;
dropArea.style.display = ‘none’;
controlsWrapper.style.display = ‘block’;
interactionInstructions.style.display = ‘block’;
actionButtonsContainer.style.display = ‘flex’;
// Reset watermark size
watermarkImg.style.width = ‘100px’;
// Default social toggle to ON
socialToggle.checked = true;
socialOverlay.classList.add(‘active’);
// Set default position to bottom-right of the social circle
setTimeout(() => {
const centerX = imageContainer.clientWidth / 2;
const centerY = imageContainer.clientHeight / 2;
const radius = Math.min(imageContainer.clientWidth, imageContainer.clientHeight) / 2;
// Offset from center towards bottom-right (45 degrees)
// Using a factor of 0.7 to place it near the edge (4:30 position)
const dist = radius * 0.7;
const angle = Math.PI / 4; // 45 degrees
const defaultLeft = centerX + dist * Math.cos(angle) – (watermark.offsetWidth / 2);
const defaultTop = centerY + dist * Math.sin(angle) – (watermark.offsetHeight / 2);
watermark.style.left = Math.max(0, defaultLeft) + ‘px’;
watermark.style.top = Math.max(0, defaultTop) + ‘px’;
// Add pulse animation to highlight the resize handle
resizeHandle.classList.add(‘pulse’);
}, 0);
};
originalImageObj.src = e.target.result;
};
reader.readAsDataURL(file);
}
}
// — Resizing Logic (Handle) —
resizeHandle.addEventListener(‘mousedown’, initResize);
resizeHandle.addEventListener(‘touchstart’, initResize, {passive: false});
function initResize(e) {
e.stopPropagation(); // Prevent drag start
if(e.type === ‘touchstart’) e.preventDefault();
isResizing = true;
resizeHandle.classList.remove(‘pulse’);
const clientX = e.type === ‘touchstart’ ? e.touches[0].clientX : e.clientX;
resizeStartX = clientX;
resizeStartWidth = watermarkImg.offsetWidth;
document.addEventListener(‘mousemove’, resizeMove);
document.addEventListener(‘mouseup’, resizeEnd);
document.addEventListener(‘touchmove’, resizeMove, {passive: false});
document.addEventListener(‘touchend’, resizeEnd);
}
function resizeMove(e) {
if (!isResizing) return;
if(e.type === ‘touchmove’) e.preventDefault();
const clientX = e.type === ‘touchmove’ ? e.touches[0].clientX : e.clientX;
// Calculate new width: original width + (mouse delta)
const dx = clientX – resizeStartX;
let newWidth = resizeStartWidth + dx;
// Constraints
const minWidth = 20;
const maxWidth = imageContainer.clientWidth; // Max width is the container width
newWidth = Math.max(minWidth, Math.min(newWidth, maxWidth));
watermarkImg.style.width = newWidth + ‘px’;
}
function resizeEnd() {
isResizing = false;
document.removeEventListener(‘mousemove’, resizeMove);
document.removeEventListener(‘mouseup’, resizeEnd);
document.removeEventListener(‘touchmove’, resizeMove);
document.removeEventListener(‘touchend’, resizeEnd);
}
// — Drag Logic —
watermark.addEventListener(‘mousedown’, dragStart);
watermark.addEventListener(‘touchstart’, dragStart, {passive: false});
function dragStart(e) {
// If clicking the resize handle, don’t drag
if (e.target === resizeHandle || isResizing) return;
if(e.type === ‘touchstart’) e.preventDefault();
isDragging = true;
watermark.classList.add(‘dragging’);
const clientX = e.type === ‘touchstart’ ? e.touches[0].clientX : e.clientX;
const clientY = e.type === ‘touchstart’ ? e.touches[0].clientY : e.clientY;
dragStartX = clientX;
dragStartY = clientY;
initialLeft = watermark.offsetLeft;
initialTop = watermark.offsetTop;
document.addEventListener(‘mousemove’, dragMove);
document.addEventListener(‘mouseup’, dragEnd);
document.addEventListener(‘touchmove’, dragMove, {passive: false});
document.addEventListener(‘touchend’, dragEnd);
}
function dragMove(e) {
if (!isDragging) return;
if(e.type === ‘touchmove’) e.preventDefault();
const clientX = e.type === ‘touchmove’ ? e.touches[0].clientX : e.clientX;
const clientY = e.type === ‘touchmove’ ? e.touches[0].clientY : e.clientY;
const dx = clientX – dragStartX;
const dy = clientY – dragStartY;
let newLeft = initialLeft + dx;
let newTop = initialTop + dy;
// Boundary checks relative to the displayed image container
const maxLeft = imageContainer.clientWidth – watermark.offsetWidth;
const maxTop = imageContainer.clientHeight – watermark.offsetHeight;
newLeft = Math.max(0, Math.min(newLeft, maxLeft));
newTop = Math.max(0, Math.min(newTop, maxTop));
watermark.style.left = newLeft + ‘px’;
watermark.style.top = newTop + ‘px’;
}
function dragEnd() {
isDragging = false;
watermark.classList.remove(‘dragging’);
document.removeEventListener(‘mousemove’, dragMove);
document.removeEventListener(‘mouseup’, dragEnd);
document.removeEventListener(‘touchmove’, dragMove);
document.removeEventListener(‘touchend’, dragEnd);
}
// — Download Logic —
downloadBtn.addEventListener(‘click’, function() {
if (!originalImageObj.src) return;
if (!canvasSupported) {
alert(‘Your browser does not support image export.’);
return;
}
// 1. Calculate Scale Factor
// The image displayed on screen might be smaller (CSS max-width) than the real image.
// We need to scale the watermark coordinates and size up to the real image size.
// displayed width / real width
// Wait! We want: real / displayed to scale UP the coordinates.
const displayedWidth = mainImage.clientWidth; // Width as rendered in DOM
const displayedHeight = mainImage.clientHeight;
const realWidth = originalImageObj.width;
const realHeight = originalImageObj.height;
const scaleX = realWidth / displayedWidth;
const scaleY = realHeight / displayedHeight;
// 2. Setup High-Res Canvas
const canvas = document.createElement(‘canvas’);
canvas.width = realWidth;
canvas.height = realHeight;
const ctx = canvas.getContext(‘2d’);
// 3. Draw Original Image
ctx.drawImage(originalImageObj, 0, 0);
// 4. Calculate Watermark Position & Size
const wmLeft = watermark.offsetLeft * scaleX;
const wmTop = watermark.offsetTop * scaleY;
// The watermark container width might be wrapper, use the img inside for size
const wmCurrentWidth = watermarkImg.offsetWidth;
const wmCurrentHeight = watermarkImg.offsetHeight;
const wmRealWidth = wmCurrentWidth * scaleX;
const wmRealHeight = wmCurrentHeight * scaleY;
// 5. Draw Watermark
ctx.drawImage(watermarkImg, wmLeft, wmTop, wmRealWidth, wmRealHeight);
// 6. Export
try {
const link = document.createElement(‘a’);
link.download = originalFileName;
link.href = canvas.toDataURL(‘image/jpeg’, 0.9); // 90% quality
link.click();
} catch (err) {
console.error(‘Export failed:’, err);
alert(‘Failed to export image. This can happen if the image is too large for your browser.’);
}
});
});
Displaying script.js.