File size: 10,855 Bytes
43a8c52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ec4dbff
43a8c52
 
 
ec4dbff
 
43a8c52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ec4dbff
43a8c52
 
59dcb0c
43a8c52
 
ec4dbff
59dcb0c
bb6a6e7
43a8c52
59dcb0c
 
 
ec4dbff
43a8c52
ec4dbff
43a8c52
 
59dcb0c
43a8c52
 
 
 
 
 
ec4dbff
43a8c52
 
 
ec4dbff
43a8c52
 
 
 
 
59dcb0c
5dbb1e4
43a8c52
 
ec4dbff
 
 
 
 
 
 
 
 
 
 
 
76b0907
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ec4dbff
 
 
ca1437b
00280b6
ec4dbff
 
 
 
43a8c52
ec4dbff
 
00280b6
ca1437b
 
76b0907
 
 
 
 
 
 
ec4dbff
 
76b0907
ec4dbff
ca1437b
ec4dbff
ca1437b
ec4dbff
 
 
 
 
 
 
f4172cc
ca1437b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ec4dbff
 
 
 
ca1437b
ec4dbff
 
ca1437b
 
ec4dbff
ca1437b
 
ec4dbff
ca1437b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ec4dbff
 
ca1437b
 
 
 
 
 
 
 
 
 
 
 
 
 
ec4dbff
ca1437b
ec4dbff
9511f1a
43a8c52
ec4dbff
 
 
43a8c52
ca1437b
43a8c52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
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 = '';
    }
});