hbf0421's picture
مطمین شو تکه های ایجاد شده تمام عکس اوله را پوشش بدهد
76b0907 verified
document.addEventListener('DOMContentLoaded', function() {
// DOM Elements
const dropZone = document.getElementById('dropZone');
const imageUpload = document.getElementById('imageUpload');
const uploadBtn = document.getElementById('uploadBtn');
const generateBtn = document.getElementById('generateBtn');
const previewContainer = document.getElementById('previewContainer');
const resultsSection = document.getElementById('resultsSection');
const posterPages = document.getElementById('posterPages');
const printAllBtn = document.getElementById('printAllBtn');
const downloadAllBtn = document.getElementById('downloadAllBtn');
const resetBtn = document.getElementById('resetBtn');
const pageCount = document.getElementById('pageCount');
const orientation = document.getElementById('orientation');
const overlapX = document.getElementById('overlapX');
const overlapY = document.getElementById('overlapY');
const showGrid = document.getElementById('showGrid');
const centerOverlap = document.getElementById('centerOverlap');
let uploadedImage = null;
// Event Listeners
uploadBtn.addEventListener('click', () => imageUpload.click());
imageUpload.addEventListener('change', handleImageUpload);
dropZone.addEventListener('dragover', handleDragOver);
dropZone.addEventListener('dragleave', handleDragLeave);
dropZone.addEventListener('drop', handleDrop);
generateBtn.addEventListener('click', generatePosterPages);
printAllBtn.addEventListener('click', printAllPages);
downloadAllBtn.addEventListener('click', downloadAllPages);
resetBtn.addEventListener('click', resetApp);
// Functions
function handleImageUpload(e) {
const file = e.target.files[0];
if (file && file.type.match('image.*')) {
processImageFile(file);
}
}
function handleDragOver(e) {
e.preventDefault();
e.stopPropagation();
dropZone.classList.add('drag-over');
}
function handleDragLeave(e) {
e.preventDefault();
e.stopPropagation();
dropZone.classList.remove('drag-over');
}
function handleDrop(e) {
e.preventDefault();
e.stopPropagation();
dropZone.classList.remove('drag-over');
const file = e.dataTransfer.files[0];
if (file && file.type.match('image.*')) {
processImageFile(file);
}
}
function processImageFile(file) {
const reader = new FileReader();
reader.onload = function(e) {
uploadedImage = new Image();
uploadedImage.onload = function() {
displayPreview(uploadedImage);
generateBtn.disabled = false;
};
uploadedImage.src = e.target.result;
};
reader.readAsDataURL(file);
}
function displayPreview(image) {
previewContainer.innerHTML = '';
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const maxWidth = 400;
const maxHeight = 300;
let width = image.width;
let height = image.height;
if (width > maxWidth) {
height = (maxWidth / width) * height;
width = maxWidth;
}
if (height > maxHeight) {
width = (maxHeight / height) * width;
height = maxHeight;
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(image, 0, 0, width, height);
previewContainer.appendChild(canvas);
}
function generatePosterPages() {
if (!uploadedImage) return;
posterPages.innerHTML = '';
resultsSection.classList.remove('hidden');
const pages = parseInt(pageCount.value);
const gridSize = Math.sqrt(pages);
const orient = orientation.value;
const overlapXPx = (parseInt(overlapX.value) / 25.4) * 96; // Convert mm to pixels (96dpi)
const overlapYPx = (parseInt(overlapY.value) / 25.4) * 96; // Convert mm to pixels (96dpi)
const showGuides = showGrid.checked;
const centerOverlaps = centerOverlap.checked;
// Calculate the size of each segment including overlaps
const totalOverlapXPx = overlapXPx * (gridSize - 1);
const totalOverlapYPx = overlapYPx * (gridSize - 1);
// Original image dimensions minus total overlaps
const baseWidth = uploadedImage.width - totalOverlapXPx;
const baseHeight = uploadedImage.height - totalOverlapYPx;
const segmentWidth = baseWidth / gridSize;
const segmentHeight = baseHeight / gridSize;
// Create a canvas for each page
for (let row = 0; row < gridSize; row++) {
for (let col = 0; col < gridSize; col++) {
const pageNumber = row * gridSize + col + 1;
const pageDiv = document.createElement('div');
pageDiv.className = 'poster-page relative';
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Set canvas dimensions based on orientation
if (orient === 'landscape') {
canvas.width = 842; // A4 height as width (landscape)
canvas.height = 595; // A4 width as height (landscape)
} else {
canvas.width = 595; // A4 width in pixels at 72dpi
canvas.height = 842; // A4 height in pixels at 72dpi
}
// Calculate source rectangle with overlaps
let sx = col * (segmentWidth) + (col * overlapXPx);
let sy = row * (segmentHeight) + (row * overlapYPx);
let sw = segmentWidth + (col < gridSize-1 ? overlapXPx : 0);
let sh = segmentHeight + (row < gridSize-1 ? overlapYPx : 0);
// Ensure we don't exceed image bounds
sx = Math.max(0, Math.min(sx, uploadedImage.width - sw));
sy = Math.max(0, Math.min(sy, uploadedImage.height - sh));
sw = Math.min(sw, uploadedImage.width - sx);
sh = Math.min(sh, uploadedImage.height - sy);
// Draw the image segment
ctx.save();
if (orient === 'diagonal') {
// Diagonal orientation
ctx.translate(canvas.width/2, canvas.height/2);
ctx.rotate(Math.PI/4);
ctx.drawImage(
uploadedImage,
sx, sy, sw, sh,
-canvas.width/2, -canvas.height/2, canvas.width, canvas.height
);
} else {
// Standard orientation (portrait or landscape)
// Maintain aspect ratio while filling canvas
const imgRatio = sw / sh;
const canvasRatio = canvas.width / canvas.height;
let drawWidth, drawHeight, offsetX = 0, offsetY = 0;
if (imgRatio > canvasRatio) {
// Image is wider than canvas - fill width
drawWidth = canvas.width;
drawHeight = canvas.width / imgRatio;
offsetY = (canvas.height - drawHeight) / 2;
} else {
// Image is taller than canvas - fill height
drawHeight = canvas.height;
drawWidth = canvas.height * imgRatio;
offsetX = (canvas.width - drawWidth) / 2;
}
ctx.drawImage(
uploadedImage,
sx, sy, sw, sh,
offsetX, offsetY, drawWidth, drawHeight
);
}
// Draw cutting guides if enabled
if (showGuides) {
ctx.strokeStyle = 'rgba(255, 0, 0, 0.7)';
ctx.lineWidth = 2;
if (orient === 'portrait' || orient === 'landscape') {
// Draw border for overlap areas
const borderX = 10;
const borderY = 10;
const borderWidth = canvas.width - 20;
const borderHeight = canvas.height - 20;
ctx.strokeRect(borderX, borderY, borderWidth, borderHeight);
// Draw center marks
ctx.beginPath();
ctx.moveTo(canvas.width/2 - 15, canvas.height/2);
ctx.lineTo(canvas.width/2 + 15, canvas.height/2);
ctx.moveTo(canvas.width/2, canvas.height/2 - 15);
ctx.lineTo(canvas.width/2, canvas.height/2 + 15);
ctx.stroke();
}
}
// Draw border around the entire canvas
ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)';
ctx.lineWidth = 2;
ctx.strokeRect(0, 0, canvas.width, canvas.height);
ctx.restore();
// Add page number
const pageNumDiv = document.createElement('div');
pageNumDiv.className = 'absolute top-2 right-2 bg-white bg-opacity-80 px-2 py-1 rounded text-sm font-bold';
pageNumDiv.textContent = pageNumber;
pageDiv.appendChild(pageNumDiv);
// Add canvas to page
pageDiv.appendChild(canvas);
posterPages.appendChild(pageDiv);
}
}
// Scroll to results
resultsSection.scrollIntoView({ behavior: 'smooth' });
}
function printAllPages() {
window.print();
}
function downloadAllPages() {
alert('PDF generation would be implemented here with a library like jsPDF or browser print to PDF');
}
function resetApp() {
uploadedImage = null;
previewContainer.innerHTML = `
<i data-feather="image" class="w-16 h-16 mx-auto text-gray-400 mb-3"></i>
<p class="text-gray-600">Your image preview will appear here</p>
`;
feather.replace();
posterPages.innerHTML = '';
resultsSection.classList.add('hidden');
generateBtn.disabled = true;
imageUpload.value = '';
}
});