Spaces:
Running
Running
بخش تقسیم عکس به تکه های کوچک رو بازنویسی کن
Browse files
script.js
CHANGED
|
@@ -98,7 +98,6 @@ let uploadedImage = null;
|
|
| 98 |
|
| 99 |
previewContainer.appendChild(canvas);
|
| 100 |
}
|
| 101 |
-
|
| 102 |
function generatePosterPages() {
|
| 103 |
if (!uploadedImage) return;
|
| 104 |
|
|
@@ -112,7 +111,7 @@ let uploadedImage = null;
|
|
| 112 |
const showGuides = showGrid.checked;
|
| 113 |
const centerOverlaps = centerOverlap.checked;
|
| 114 |
|
| 115 |
-
// Calculate the size of each segment
|
| 116 |
const segmentWidth = uploadedImage.width / gridSize;
|
| 117 |
const segmentHeight = uploadedImage.height / gridSize;
|
| 118 |
|
|
@@ -124,6 +123,7 @@ let uploadedImage = null;
|
|
| 124 |
pageDiv.className = 'poster-page relative';
|
| 125 |
|
| 126 |
const canvas = document.createElement('canvas');
|
|
|
|
| 127 |
|
| 128 |
// Set canvas dimensions based on orientation
|
| 129 |
if (orient === 'landscape') {
|
|
@@ -133,38 +133,22 @@ let uploadedImage = null;
|
|
| 133 |
canvas.width = 595; // A4 width in pixels at 72dpi
|
| 134 |
canvas.height = 842; // A4 height in pixels at 72dpi
|
| 135 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 136 |
|
| 137 |
-
const ctx = canvas.getContext('2d');
|
| 138 |
-
// Calculate source rectangle with proper overlap handling
|
| 139 |
-
let sx, sy, sw, sh;
|
| 140 |
-
|
| 141 |
-
if (orient === 'diagonal') {
|
| 142 |
-
// Diagonal orientation - rotate source rectangle
|
| 143 |
-
const centerX = (col + 0.5) * segmentWidth;
|
| 144 |
-
const centerY = (row + 0.5) * segmentHeight;
|
| 145 |
-
const radius = Math.sqrt(segmentWidth*segmentWidth + segmentHeight*segmentHeight)/2;
|
| 146 |
-
|
| 147 |
-
sx = centerX - radius;
|
| 148 |
-
sy = centerY - radius;
|
| 149 |
-
sw = radius * 2;
|
| 150 |
-
sh = radius * 2;
|
| 151 |
-
} else {
|
| 152 |
-
// Standard orientation
|
| 153 |
-
// Calculate source rectangle without overlaps
|
| 154 |
-
sx = col * segmentWidth;
|
| 155 |
-
sy = row * segmentHeight;
|
| 156 |
-
sw = segmentWidth;
|
| 157 |
-
sh = segmentHeight;
|
| 158 |
-
}
|
| 159 |
// Ensure we stay within image bounds
|
| 160 |
-
sx = Math.max(0, sx);
|
| 161 |
-
sy = Math.max(0, sy);
|
| 162 |
sw = Math.min(sw, uploadedImage.width - sx);
|
| 163 |
sh = Math.min(sh, uploadedImage.height - sy);
|
| 164 |
-
|
|
|
|
| 165 |
ctx.save();
|
|
|
|
| 166 |
if (orient === 'diagonal') {
|
| 167 |
-
//
|
| 168 |
ctx.translate(canvas.width/2, canvas.height/2);
|
| 169 |
ctx.rotate(Math.PI/4);
|
| 170 |
ctx.drawImage(
|
|
@@ -172,69 +156,71 @@ let uploadedImage = null;
|
|
| 172 |
sx, sy, sw, sh,
|
| 173 |
-canvas.width/2, -canvas.height/2, canvas.width, canvas.height
|
| 174 |
);
|
| 175 |
-
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
| 176 |
} else {
|
| 177 |
-
// Standard orientation
|
| 178 |
-
//
|
| 179 |
-
const
|
| 180 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 181 |
|
| 182 |
-
// Adjust destination position based on any out-of-bounds
|
| 183 |
-
const destX = -dx * (destWidth / sw);
|
| 184 |
-
const destY = -dy * (destHeight / sh);
|
| 185 |
-
// Draw image to fill entire canvas without gaps
|
| 186 |
ctx.drawImage(
|
| 187 |
uploadedImage,
|
| 188 |
sx, sy, sw, sh,
|
| 189 |
-
|
| 190 |
);
|
| 191 |
-
}
|
| 192 |
-
// Draw border around the image segment
|
| 193 |
-
ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
|
| 194 |
-
ctx.lineWidth = 2;
|
| 195 |
-
|
| 196 |
-
if (orient === 'portrait' || orient === 'landscape') {
|
| 197 |
-
const borderX = dx > 0 ? dx * (canvas.width / sw) : 0;
|
| 198 |
-
const borderY = dy > 0 ? dy * (canvas.height / sh) : 0;
|
| 199 |
-
const borderWidth = canvas.width * (sw / (sw + dx));
|
| 200 |
-
const borderHeight = canvas.height * (sh / (sh + dy));
|
| 201 |
-
ctx.strokeRect(borderX, borderY, borderWidth, borderHeight);
|
| 202 |
-
} else {
|
| 203 |
-
ctx.strokeRect(0, 0, canvas.width, canvas.height);
|
| 204 |
}
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
ctx.lineWidth = 2;
|
| 208 |
-
ctx.strokeRect(0, 0, canvas.width, canvas.height);
|
| 209 |
-
ctx.restore();
|
| 210 |
-
// Add cutting guides if enabled
|
| 211 |
if (showGuides) {
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
// Top guide
|
| 215 |
-
if (row > 0) {
|
| 216 |
-
const topGuide = document.createElement('div');
|
| 217 |
-
topGuide.className = 'cutting-guide';
|
| 218 |
-
topGuide.style.top = '0';
|
| 219 |
-
topGuide.style.left = '0';
|
| 220 |
-
topGuide.style.width = '100%';
|
| 221 |
-
topGuide.style.height = `${guideSize}px`;
|
| 222 |
-
pageDiv.appendChild(topGuide);
|
| 223 |
-
}
|
| 224 |
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
const
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 234 |
}
|
| 235 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 236 |
// Add canvas to page
|
| 237 |
-
pageDiv.appendChild(canvas);
|
| 238 |
posterPages.appendChild(pageDiv);
|
| 239 |
}
|
| 240 |
}
|
|
@@ -242,8 +228,7 @@ pageDiv.appendChild(canvas);
|
|
| 242 |
// Scroll to results
|
| 243 |
resultsSection.scrollIntoView({ behavior: 'smooth' });
|
| 244 |
}
|
| 245 |
-
|
| 246 |
-
function printAllPages() {
|
| 247 |
window.print();
|
| 248 |
}
|
| 249 |
|
|
|
|
| 98 |
|
| 99 |
previewContainer.appendChild(canvas);
|
| 100 |
}
|
|
|
|
| 101 |
function generatePosterPages() {
|
| 102 |
if (!uploadedImage) return;
|
| 103 |
|
|
|
|
| 111 |
const showGuides = showGrid.checked;
|
| 112 |
const centerOverlaps = centerOverlap.checked;
|
| 113 |
|
| 114 |
+
// Calculate the size of each segment including overlaps
|
| 115 |
const segmentWidth = uploadedImage.width / gridSize;
|
| 116 |
const segmentHeight = uploadedImage.height / gridSize;
|
| 117 |
|
|
|
|
| 123 |
pageDiv.className = 'poster-page relative';
|
| 124 |
|
| 125 |
const canvas = document.createElement('canvas');
|
| 126 |
+
const ctx = canvas.getContext('2d');
|
| 127 |
|
| 128 |
// Set canvas dimensions based on orientation
|
| 129 |
if (orient === 'landscape') {
|
|
|
|
| 133 |
canvas.width = 595; // A4 width in pixels at 72dpi
|
| 134 |
canvas.height = 842; // A4 height in pixels at 72dpi
|
| 135 |
}
|
| 136 |
+
|
| 137 |
+
// Calculate source rectangle with overlaps
|
| 138 |
+
let sx = Math.max(0, col * segmentWidth - (col > 0 ? overlapXPx/2 : 0));
|
| 139 |
+
let sy = Math.max(0, row * segmentHeight - (row > 0 ? overlapYPx/2 : 0));
|
| 140 |
+
let sw = segmentWidth + (col === 0 || col === gridSize-1 ? overlapXPx/2 : overlapXPx);
|
| 141 |
+
let sh = segmentHeight + (row === 0 || row === gridSize-1 ? overlapYPx/2 : overlapYPx);
|
| 142 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
// Ensure we stay within image bounds
|
|
|
|
|
|
|
| 144 |
sw = Math.min(sw, uploadedImage.width - sx);
|
| 145 |
sh = Math.min(sh, uploadedImage.height - sy);
|
| 146 |
+
|
| 147 |
+
// Draw the image segment
|
| 148 |
ctx.save();
|
| 149 |
+
|
| 150 |
if (orient === 'diagonal') {
|
| 151 |
+
// Diagonal orientation
|
| 152 |
ctx.translate(canvas.width/2, canvas.height/2);
|
| 153 |
ctx.rotate(Math.PI/4);
|
| 154 |
ctx.drawImage(
|
|
|
|
| 156 |
sx, sy, sw, sh,
|
| 157 |
-canvas.width/2, -canvas.height/2, canvas.width, canvas.height
|
| 158 |
);
|
|
|
|
| 159 |
} else {
|
| 160 |
+
// Standard orientation (portrait or landscape)
|
| 161 |
+
// Maintain aspect ratio while filling canvas
|
| 162 |
+
const imgRatio = sw / sh;
|
| 163 |
+
const canvasRatio = canvas.width / canvas.height;
|
| 164 |
+
|
| 165 |
+
let drawWidth, drawHeight, offsetX = 0, offsetY = 0;
|
| 166 |
+
|
| 167 |
+
if (imgRatio > canvasRatio) {
|
| 168 |
+
// Image is wider than canvas - fill width
|
| 169 |
+
drawWidth = canvas.width;
|
| 170 |
+
drawHeight = canvas.width / imgRatio;
|
| 171 |
+
offsetY = (canvas.height - drawHeight) / 2;
|
| 172 |
+
} else {
|
| 173 |
+
// Image is taller than canvas - fill height
|
| 174 |
+
drawHeight = canvas.height;
|
| 175 |
+
drawWidth = canvas.height * imgRatio;
|
| 176 |
+
offsetX = (canvas.width - drawWidth) / 2;
|
| 177 |
+
}
|
| 178 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
ctx.drawImage(
|
| 180 |
uploadedImage,
|
| 181 |
sx, sy, sw, sh,
|
| 182 |
+
offsetX, offsetY, drawWidth, drawHeight
|
| 183 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
}
|
| 185 |
+
|
| 186 |
+
// Draw cutting guides if enabled
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
if (showGuides) {
|
| 188 |
+
ctx.strokeStyle = 'rgba(255, 0, 0, 0.7)';
|
| 189 |
+
ctx.lineWidth = 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
|
| 191 |
+
if (orient === 'portrait' || orient === 'landscape') {
|
| 192 |
+
// Draw border for overlap areas
|
| 193 |
+
const borderX = 10;
|
| 194 |
+
const borderY = 10;
|
| 195 |
+
const borderWidth = canvas.width - 20;
|
| 196 |
+
const borderHeight = canvas.height - 20;
|
| 197 |
+
ctx.strokeRect(borderX, borderY, borderWidth, borderHeight);
|
| 198 |
+
|
| 199 |
+
// Draw center marks
|
| 200 |
+
ctx.beginPath();
|
| 201 |
+
ctx.moveTo(canvas.width/2 - 15, canvas.height/2);
|
| 202 |
+
ctx.lineTo(canvas.width/2 + 15, canvas.height/2);
|
| 203 |
+
ctx.moveTo(canvas.width/2, canvas.height/2 - 15);
|
| 204 |
+
ctx.lineTo(canvas.width/2, canvas.height/2 + 15);
|
| 205 |
+
ctx.stroke();
|
| 206 |
}
|
| 207 |
}
|
| 208 |
+
|
| 209 |
+
// Draw border around the entire canvas
|
| 210 |
+
ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)';
|
| 211 |
+
ctx.lineWidth = 2;
|
| 212 |
+
ctx.strokeRect(0, 0, canvas.width, canvas.height);
|
| 213 |
+
|
| 214 |
+
ctx.restore();
|
| 215 |
+
|
| 216 |
+
// Add page number
|
| 217 |
+
const pageNumDiv = document.createElement('div');
|
| 218 |
+
pageNumDiv.className = 'absolute top-2 right-2 bg-white bg-opacity-80 px-2 py-1 rounded text-sm font-bold';
|
| 219 |
+
pageNumDiv.textContent = pageNumber;
|
| 220 |
+
pageDiv.appendChild(pageNumDiv);
|
| 221 |
+
|
| 222 |
// Add canvas to page
|
| 223 |
+
pageDiv.appendChild(canvas);
|
| 224 |
posterPages.appendChild(pageDiv);
|
| 225 |
}
|
| 226 |
}
|
|
|
|
| 228 |
// Scroll to results
|
| 229 |
resultsSection.scrollIntoView({ behavior: 'smooth' });
|
| 230 |
}
|
| 231 |
+
function printAllPages() {
|
|
|
|
| 232 |
window.print();
|
| 233 |
}
|
| 234 |
|