netgescon-day0/resources/views/filament/print/dymo-calibrazione.blade.php

387 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Calibrazione etichetta DYMO</title>
@php
$w = ($format === '99014') ? 101 : 57;
$h = ($format === '99014') ? 54 : 32;
$dymoFix = isset($dymoFix) ? (bool) $dymoFix : false;
$rot = isset($rot) ? (int) $rot : 0;
$dx = isset($dx) ? (float) $dx : 0.0;
$dy = isset($dy) ? (float) $dy : 0.0;
$autoPrint = request()->has('autoprint') && filter_var(request()->query('autoprint'), FILTER_VALIDATE_BOOL);
// Quando il driver DYMO ruota/ritaglia in modo diverso, alcuni transform finiscono fuori pagina.
// dymo_mode permette di provare preset alternativi senza cambiare codice.
$dymoMode = strtoupper(trim((string) request()->query('dymo_mode', 'A')));
if (! in_array($dymoMode, ['A', 'B'], true)) {
$dymoMode = 'A';
}
$base = url()->current();
$qsBase = [
'format' => $format,
];
$presetA = $base . '?' . http_build_query(array_merge($qsBase, ['dymo_fix' => 0, 'rot' => 0, 'dx' => $dx, 'dy' => $dy]));
$presetB = $base . '?' . http_build_query(array_merge($qsBase, ['dymo_fix' => 0, 'rot' => 90, 'dx' => $dx, 'dy' => $dy]));
$presetC = $base . '?' . http_build_query(array_merge($qsBase, ['dymo_fix' => 1, 'rot' => -90, 'dx' => $dx, 'dy' => $dy]));
$presetD = $base . '?' . http_build_query(array_merge($qsBase, ['dymo_fix' => 1, 'rot' => 90, 'dx' => $dx, 'dy' => $dy]));
$presetC2 = $base . '?' . http_build_query(array_merge($qsBase, ['dymo_fix' => 1, 'dymo_mode' => 'B', 'rot' => -90, 'dx' => $dx, 'dy' => $dy]));
$presetD2 = $base . '?' . http_build_query(array_merge($qsBase, ['dymo_fix' => 1, 'dymo_mode' => 'B', 'rot' => 90, 'dx' => $dx, 'dy' => $dy]));
$qsCurrent = [
'format' => $format,
'dymo_fix' => $dymoFix ? 1 : 0,
'dymo_mode' => $dymoMode,
'rot' => $rot,
];
$urlDxDy = function (float $newDx, float $newDy) use ($base, $qsCurrent): string {
return $base . '?' . http_build_query(array_merge($qsCurrent, [
'dx' => number_format($newDx, 2, '.', ''),
'dy' => number_format($newDy, 2, '.', ''),
]));
};
$dxPlus05 = $urlDxDy($dx + 0.5, $dy);
$dxMinus05 = $urlDxDy($dx - 0.5, $dy);
$dyPlus05 = $urlDxDy($dx, $dy + 0.5);
$dyMinus05 = $urlDxDy($dx, $dy - 0.5);
$dxPlus1 = $urlDxDy($dx + 1.0, $dy);
$dxMinus1 = $urlDxDy($dx - 1.0, $dy);
$dyPlus1 = $urlDxDy($dx, $dy + 1.0);
$dyMinus1 = $urlDxDy($dx, $dy - 1.0);
@endphp
<style>
:root {
--w: {{ $w }}mm;
--h: {{ $h }}mm;
}
@page {
size: var(--w) var(--h);
margin: 0;
}
html, body {
margin: 0;
padding: 0;
width: var(--w);
height: var(--h);
background: #fff;
overflow: hidden;
}
.sheet {
position: relative;
width: var(--w);
height: var(--h);
overflow: hidden;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
break-inside: avoid;
break-after: avoid-page;
page-break-inside: avoid;
page-break-after: avoid;
}
.calib {
position: absolute;
inset: 0;
transform-origin: 0 0;
}
@media print {
/* Default: offset + rot su pagina (utile per 99014 e per 11354 se il driver non ruota) */
@if(!($format === '11354' && $dymoFix))
.calib {
transform: translate({{ number_format($dx, 2, '.', '') }}mm, {{ number_format($dy, 2, '.', '') }}mm) rotate({{ (int) $rot }}deg);
}
@endif
/* Evita "seconda pagina" dovuta a arrotondamenti mm->px in alcuni browser */
html, body { width: 100%; height: 100%; overflow: hidden; }
.sheet { position: fixed; left: 0; top: 0; }
/*
* DYMO 11354 workaround:
* alcuni driver stampano la 57x32 ruotata. In quel caso impostiamo la pagina a 32x57
* e ruotiamo il contenuto interno 57x32.
*/
@if($format === '11354' && $dymoFix)
@page { size: 32mm 57mm; }
html, body { width: 32mm; height: 57mm; }
.sheet { width: 32mm; height: 57mm; }
.calib {
width: 57mm;
height: 32mm;
@php($r = (int) $rot)
@if($dymoMode === 'B')
/* Mode B: alternative origin/translation (useful when C/D are blank) */
@if($r === 90)
transform: translate({{ number_format($dx, 2, '.', '') }}mm, {{ number_format($dy, 2, '.', '') }}mm) translateX(57mm) rotate(90deg);
@else
transform: translate({{ number_format($dx, 2, '.', '') }}mm, {{ number_format($dy, 2, '.', '') }}mm) translateY(32mm) rotate(-90deg);
@endif
@else
/* Mode A: default */
@if($r === 90)
transform: translate({{ number_format($dx, 2, '.', '') }}mm, {{ number_format($dy, 2, '.', '') }}mm) translateX(32mm) rotate(90deg);
@else
transform: translate({{ number_format($dx, 2, '.', '') }}mm, {{ number_format($dy, 2, '.', '') }}mm) translateY(57mm) rotate(-90deg);
@endif
@endif
}
@endif
}
/* Grid: 1mm light + 5mm stronger */
.grid {
position: absolute;
inset: 0;
background-image:
repeating-linear-gradient(0deg, rgba(0,0,0,0.08), rgba(0,0,0,0.08) 0.2mm, transparent 0.2mm, transparent 1mm),
repeating-linear-gradient(90deg, rgba(0,0,0,0.08), rgba(0,0,0,0.08) 0.2mm, transparent 0.2mm, transparent 1mm),
repeating-linear-gradient(0deg, rgba(0,0,0,0.20), rgba(0,0,0,0.20) 0.35mm, transparent 0.35mm, transparent 5mm),
repeating-linear-gradient(90deg, rgba(0,0,0,0.20), rgba(0,0,0,0.20) 0.35mm, transparent 0.35mm, transparent 5mm);
}
.border {
position: absolute;
inset: 0;
border: 0.4mm solid #000;
box-sizing: border-box;
}
.center {
position: absolute;
left: 50%;
top: 50%;
width: 12mm;
height: 12mm;
margin-left: -6mm;
margin-top: -6mm;
border: 0.5mm solid #000;
box-sizing: border-box;
}
.cross {
position: absolute;
left: 50%;
top: 50%;
width: 0;
height: 0;
}
.cross::before,
.cross::after {
content: '';
position: absolute;
background: #000;
}
.cross::before {
width: 18mm;
height: 0.6mm;
left: -9mm;
top: -0.3mm;
}
.cross::after {
width: 0.6mm;
height: 18mm;
left: -0.3mm;
top: -9mm;
}
.label {
position: absolute;
left: 1.5mm;
top: 1.2mm;
font: 2.8mm/1.2 sans-serif;
color: #000;
background: rgba(255,255,255,0.85);
padding: 0.6mm 0.8mm;
border: 0.2mm solid rgba(0,0,0,0.4);
}
.help {
position: absolute;
left: 1.5mm;
bottom: 1.2mm;
font: 2.6mm/1.25 sans-serif;
color: #000;
background: rgba(255,255,255,0.85);
padding: 0.6mm 0.8mm;
border: 0.2mm solid rgba(0,0,0,0.35);
max-width: calc(100% - 3mm);
box-sizing: border-box;
}
.orient {
position: absolute;
inset: 0;
pointer-events: none;
}
.orient .top {
position: absolute;
left: 50%;
top: 1.2mm;
transform: translateX(-50%);
font: 3mm/1 sans-serif;
font-weight: 800;
letter-spacing: .6px;
background: rgba(255,255,255,0.85);
padding: 0.4mm 0.6mm;
border: 0.2mm solid rgba(0,0,0,0.35);
}
.orient .left {
position: absolute;
left: 1.2mm;
top: 50%;
transform: translateY(-50%) rotate(-90deg);
transform-origin: left top;
font: 3mm/1 sans-serif;
font-weight: 800;
letter-spacing: .6px;
background: rgba(255,255,255,0.85);
padding: 0.4mm 0.6mm;
border: 0.2mm solid rgba(0,0,0,0.35);
}
.corner {
position: absolute;
width: 6mm;
height: 6mm;
box-sizing: border-box;
border: 0.6mm solid #000;
}
.corner.tl { left: 0; top: 0; border-right: 0; border-bottom: 0; }
.corner.tr { right: 0; top: 0; border-left: 0; border-bottom: 0; }
.corner.bl { left: 0; bottom: 0; border-right: 0; border-top: 0; }
.corner.br { right: 0; bottom: 0; border-left: 0; border-top: 0; }
@media screen {
body {
padding: 12px;
background: #f3f4f6;
}
.sheet {
box-shadow: 0 0 0 1px rgba(0,0,0,0.15);
}
.toolbar {
display: flex;
flex-wrap: wrap;
gap: 8px;
align-items: center;
margin: 0 0 10px 0;
}
.toolbar .hint {
font: 13px/1.2 sans-serif;
color: #111827;
}
.toolbar button {
appearance: none;
border: 1px solid rgba(0,0,0,0.25);
background: #fff;
padding: 6px 10px;
border-radius: 6px;
cursor: pointer;
font: 13px/1.2 sans-serif;
}
.toolbar a.btn {
display: inline-block;
border: 1px solid rgba(0,0,0,0.25);
background: #fff;
padding: 6px 10px;
border-radius: 6px;
cursor: pointer;
font: 13px/1.2 sans-serif;
color: #111827;
text-decoration: none;
}
.toolbar .group {
display: inline-flex;
gap: 6px;
align-items: center;
padding: 4px 6px;
border: 1px dashed rgba(0,0,0,0.18);
border-radius: 8px;
background: rgba(255,255,255,0.65);
}
}
@media print {
.no-print { display: none !important; }
}
</style>
@if($autoPrint)
<script>
window.addEventListener('load', () => {
// Alcuni browser bloccano print() senza gesto utente: se succede, usa il bottone “Stampa”.
setTimeout(() => {
try { window.print(); } catch (e) {}
}, 120);
});
</script>
@endif
</head>
<body>
<div class="toolbar no-print">
<button type="button" onclick="window.print()">Stampa</button>
<a href="{{ $presetA }}" class="btn">Preset A (fix=0 rot=0)</a>
<a href="{{ $presetB }}" class="btn">Preset B (fix=0 rot=90)</a>
<a href="{{ $presetC }}" class="btn">Preset C (fix=1 rot=-90)</a>
<a href="{{ $presetD }}" class="btn">Preset D (fix=1 rot=90)</a>
<a href="{{ $presetC2 }}" class="btn">Preset C2 (fix=1 mode=B rot=-90)</a>
<a href="{{ $presetD2 }}" class="btn">Preset D2 (fix=1 mode=B rot=90)</a>
<span class="group">
<span class="hint">dx</span>
<a href="{{ $dxMinus1 }}" class="btn">1</a>
<a href="{{ $dxMinus05 }}" class="btn">0.5</a>
<a href="{{ $dxPlus05 }}" class="btn">+0.5</a>
<a href="{{ $dxPlus1 }}" class="btn">+1</a>
</span>
<span class="group">
<span class="hint">dy</span>
<a href="{{ $dyMinus1 }}" class="btn">1</a>
<a href="{{ $dyMinus05 }}" class="btn">0.5</a>
<a href="{{ $dyPlus05 }}" class="btn">+0.5</a>
<a href="{{ $dyPlus1 }}" class="btn">+1</a>
</span>
<div class="hint" style="flex-basis: 100%;">
Nota: se A/B risultano “vuoti” o stampano spostati, usa C/D (fix=1). Se C/D stampano ma risultano troppo a sinistra/destra, correggi con dx/dy.
</div>
</div>
<div class="sheet">
<div class="calib">
<div class="grid"></div>
<div class="border"></div>
<div class="corner tl"></div>
<div class="corner tr"></div>
<div class="corner bl"></div>
<div class="corner br"></div>
<div class="center"></div>
<div class="cross"></div>
<div class="orient">
<div class="top">TOP</div>
<div class="left">LEFT</div>
</div>
<div class="label">
DYMO {{ $format }} ({{ $w }}×{{ $h }}mm) · fix={{ $dymoFix ? '1' : '0' }} · mode={{ $dymoMode }} · dx={{ number_format($dx, 2, '.', '') }}mm · dy={{ number_format($dy, 2, '.', '') }}mm · rot={{ (int) $rot }}°
</div>
<div class="help">
Prova rapida 11354: aggiungi <strong>?format=11354&dymo_fix=1</strong> (se ruotata), poi regola <strong>dx/dy</strong> in mm.
</div>
</div>
</div>
</body>
</html>