Skip to content

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.