Fix design spec SVG overlay and decimal point in measurements
- Use preserveAspectRatio='none' to properly scale SVG lines to image - Fix measurement formula: subtract print area offset, multiply by mmPerPx - Add axis labels showing 0cm origin points - Correct decimal precision in all dimension calculations - Lines now properly overlay on product mockup image
This commit is contained in:
@@ -40,21 +40,31 @@ export async function GET(req: Request, { params }: { params: { id: string } })
|
||||
hPct: number;
|
||||
};
|
||||
|
||||
const printAreaStartX = DISPLAY * (printArea.xPct / 100);
|
||||
const printAreaStartY = DISPLAY * (printArea.yPct / 100);
|
||||
const printAreaWidthPx = DISPLAY * (printArea.wPct / 100);
|
||||
const printAreaHeightPx = DISPLAY * (printArea.hPct / 100);
|
||||
|
||||
// Scale: how many pixels per millimeter
|
||||
const pxPerMm = printAreaWidthPx / printAreaWidthMm;
|
||||
// Scale: how many millimeters per pixel
|
||||
const mmPerPx = printAreaWidthMm / printAreaWidthPx;
|
||||
|
||||
// Convert pixel measurements to CM (divide by pxPerMm to get mm, then divide by 10 for cm)
|
||||
const convertToCm = (px: number) => {
|
||||
const mm = px / pxPerMm;
|
||||
// Convert pixel measurements to CM
|
||||
// First: subtract the print area offset to get position within print area
|
||||
// Then: multiply by mmPerPx to get millimeters
|
||||
// Finally: divide by 10 to get centimeters
|
||||
const convertToCm = (px: number, elementPx: number | null = null) => {
|
||||
if (elementPx !== null) {
|
||||
// For element positions: subtract offset and scale
|
||||
const relativeToStart = elementPx - px;
|
||||
const mm = Math.max(0, relativeToStart * mmPerPx);
|
||||
return (mm / 10).toFixed(1);
|
||||
} else {
|
||||
// For dimensions: just scale
|
||||
const mm = px * mmPerPx;
|
||||
return (mm / 10).toFixed(1);
|
||||
}
|
||||
};
|
||||
|
||||
const printAreaStartX = DISPLAY * (printArea.xPct / 100);
|
||||
const printAreaStartY = DISPLAY * (printArea.yPct / 100);
|
||||
|
||||
const generateDesignSection = (designElements: any[], side: 'Front' | 'Back', placement: string | null, designPreview: string | null) => {
|
||||
if (!designElements || designElements.length === 0) return '';
|
||||
|
||||
@@ -68,31 +78,38 @@ export async function GET(req: Request, { params }: { params: { id: string } })
|
||||
|
||||
${placement ? `
|
||||
<div class="mockup-container">
|
||||
<p><em>Design on product (reference only) — with measurement guides</em></p>
|
||||
<div style="position: relative; display: inline-block; max-width: 100%; max-height: 400px;">
|
||||
<img src="${placement}" alt="${side} design placement" class="mockup-image" style="max-height: 400px; width: auto; display: block;">
|
||||
<svg style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none;" viewBox="0 0 ${DISPLAY} ${DISPLAY}">
|
||||
<p><em>Design on product with measurement guides</em></p>
|
||||
<div style="position: relative; display: inline-block; margin: 15px 0;">
|
||||
<img src="${placement}" alt="${side} design placement" class="mockup-image" style="max-height: 400px; width: auto; display: block; border: 1px solid #ddd;">
|
||||
<svg style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none;" preserveAspectRatio="none">
|
||||
<!-- Print area border -->
|
||||
<rect x="${printAreaStartX}" y="${printAreaStartY}" width="${printAreaWidthPx}" height="${printAreaHeightPx}" fill="none" stroke="#ff0000" stroke-width="2" stroke-dasharray="5,5" opacity="0.7"/>
|
||||
<rect x="${printAreaStartX}" y="${printAreaStartY}" width="${printAreaWidthPx}" height="${printAreaHeightPx}"
|
||||
fill="none" stroke="red" stroke-width="2" stroke-dasharray="5,5" opacity="0.8"/>
|
||||
|
||||
<!-- X-axis line -->
|
||||
<line x1="${printAreaStartX}" y1="${printAreaStartY}" x2="${printAreaStartX + printAreaWidthPx}" y2="${printAreaStartY}" stroke="#0066ff" stroke-width="1" opacity="0.5"/>
|
||||
<!-- X-axis line (horizontal) -->
|
||||
<line x1="${printAreaStartX}" y1="${printAreaStartY}" x2="${printAreaStartX + printAreaWidthPx}" y2="${printAreaStartY}"
|
||||
stroke="blue" stroke-width="1.5" opacity="0.6"/>
|
||||
|
||||
<!-- Y-axis line -->
|
||||
<line x1="${printAreaStartX}" y1="${printAreaStartY}" x2="${printAreaStartX}" y2="${printAreaStartY + printAreaHeightPx}" stroke="#00cc00" stroke-width="1" opacity="0.5"/>
|
||||
<!-- Y-axis line (vertical) -->
|
||||
<line x1="${printAreaStartX}" y1="${printAreaStartY}" x2="${printAreaStartX}" y2="${printAreaStartY + printAreaHeightPx}"
|
||||
stroke="green" stroke-width="1.5" opacity="0.6"/>
|
||||
|
||||
<!-- Design elements with coordinate markers -->
|
||||
<!-- Axis labels -->
|
||||
<text x="${printAreaStartX + 5}" y="${printAreaStartY - 5}" font-size="12" fill="blue" font-weight="bold">X (0cm)</text>
|
||||
<text x="${printAreaStartX - 25}" y="${printAreaStartY + 15}" font-size="12" fill="green" font-weight="bold">Y (0cm)</text>
|
||||
|
||||
<!-- Design elements with markers -->
|
||||
${designElements.map((el, idx) => `
|
||||
<circle cx="${el.x}" cy="${el.y}" r="4" fill="#ff6600" opacity="0.9"/>
|
||||
<text x="${el.x + 8}" y="${el.y - 8}" font-size="11" fill="#ff6600" font-weight="bold" font-family="monospace">E${idx + 1}</text>
|
||||
<circle cx="${el.x}" cy="${el.y}" r="5" fill="orange" opacity="0.9" stroke="white" stroke-width="1"/>
|
||||
<text x="${el.x + 10}" y="${el.y - 10}" font-size="12" fill="orange" font-weight="bold" font-family="monospace">E${idx + 1}</text>
|
||||
`).join('')}
|
||||
</svg>
|
||||
</div>
|
||||
<div style="margin-top: 15px; font-size: 12px; color: #666; text-align: left;">
|
||||
<p style="margin: 5px 0;"><strong style="color: #ff0000;">━━ Red dashed:</strong> Print area boundary</p>
|
||||
<p style="margin: 5px 0;"><strong style="color: #0066ff;">━ Blue:</strong> X-axis (0cm at left)</p>
|
||||
<p style="margin: 5px 0;"><strong style="color: #00cc00;">━ Green:</strong> Y-axis (0cm at top)</p>
|
||||
<p style="margin: 5px 0;"><strong style="color: #ff6600;">● Orange circles:</strong> Element positions with labels (E1, E2, etc.)</p>
|
||||
<div style="margin-top: 15px; font-size: 12px; color: #666; text-align: left; max-width: 400px;">
|
||||
<p style="margin: 5px 0;"><strong style="color: red;">━━ Red dashed line:</strong> Print area boundary</p>
|
||||
<p style="margin: 5px 0;"><strong style="color: blue;">━ Blue line:</strong> X-axis (horizontal, 0cm at left)</p>
|
||||
<p style="margin: 5px 0;"><strong style="color: green;">━ Green line:</strong> Y-axis (vertical, 0cm at top)</p>
|
||||
<p style="margin: 5px 0;"><strong style="color: orange;">● Orange circles:</strong> Element positions (E1, E2, etc.)</p>
|
||||
</div>
|
||||
</div>
|
||||
` : ''}
|
||||
@@ -112,11 +129,11 @@ export async function GET(req: Request, { params }: { params: { id: string } })
|
||||
<tr>
|
||||
<td>E${idx + 1}</td>
|
||||
<td class="element-type">${el.type === 'text' ? '📝 Text' : '🖼️ Image'}</td>
|
||||
<td>X: ${convertToCm(el.x)} | Y: ${convertToCm(el.y)}</td>
|
||||
<td>X: ${convertToCm(printAreaStartX, el.x)} | Y: ${convertToCm(printAreaStartY, el.y)}</td>
|
||||
<td>${el.type === 'image' ? `${convertToCm(el.width)} × ${convertToCm(el.height)}` : 'N/A'}</td>
|
||||
<td>
|
||||
${el.type === 'text' ? `
|
||||
Font: ${el.fontFamily}, ${Math.round(el.fontSize / pxPerMm * 10 / 10)}pt<br>
|
||||
Font: ${el.fontFamily}, ${Math.round(el.fontSize * mmPerPx / 10)}pt<br>
|
||||
Color: ${el.fill}<br>
|
||||
Text: "${el.text}"<br>
|
||||
Rotation: ${Math.round(el.rotation)}°
|
||||
@@ -173,8 +190,7 @@ export async function GET(req: Request, { params }: { params: { id: string } })
|
||||
.mockup-image {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
border: 1px solid #ddd;
|
||||
margin: 10px 0;
|
||||
display: block;
|
||||
}
|
||||
.measurements-table {
|
||||
width: 100%;
|
||||
@@ -226,8 +242,8 @@ export async function GET(req: Request, { params }: { params: { id: string } })
|
||||
<p><strong>Notes:</strong></p>
|
||||
<ul>
|
||||
<li>All measurements are in centimeters (CM)</li>
|
||||
<li>Coordinates are measured from top-left of the printable area (0,0)</li>
|
||||
<li>X-axis runs left-to-right | Y-axis runs top-to-bottom</li>
|
||||
<li>X-axis: 0cm at left edge of print area, increases to the right</li>
|
||||
<li>Y-axis: 0cm at top edge of print area, increases downward</li>
|
||||
<li>Print the design files separately for production</li>
|
||||
<li>This specification sheet is for reference and planning only</li>
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user