fix(badges): shrink punch-hole markers horizontally, add inset_x_mm config
Default horizontal inset increased from 1mm to 2mm per side (width shrinks by 4mm total) so markers stay inside the physical hole slot on all printers and badge stock with minor registration variance. Vertical stays at 1mm. The inset is now driven by punch_holes_inset_x (template_cfg.punch_holes .inset_x_mm, default 2) so it can be tuned per template without a code change. Added inset_x_mm field to AeBadgeTemplateCfg type with doc comment. All 9 slot marker divs (6 rainbow + 3 solid) updated via replace_all. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -76,6 +76,10 @@ export interface BadgeTemplateCfg {
|
||||
center_bg?: string;
|
||||
center_rainbow?: boolean;
|
||||
slow_pulse?: boolean; // when true: slow breathing pulse instead of fast linear cycle
|
||||
// Extra horizontal inset per side (mm) beyond the 1mm base safety margin.
|
||||
// Shrinks the visible marker width to keep it inside the physical hole on
|
||||
// printers or badge stock with variance. Default 2 when unset (see view component).
|
||||
inset_x_mm?: number;
|
||||
};
|
||||
|
||||
// Allow arbitrary extra keys to preserve forward-compatibility.
|
||||
|
||||
@@ -332,6 +332,11 @@ let punch_holes_left = $derived(!!template_cfg?.punch_holes?.left);
|
||||
let punch_holes_right = $derived(!!template_cfg?.punch_holes?.right);
|
||||
let punch_holes_center = $derived(!!template_cfg?.punch_holes?.center);
|
||||
|
||||
// Horizontal inset per side applied to each marker, in mm.
|
||||
// Default 2mm — enough to stay inside the hole on real badge stock with typical printer variance.
|
||||
// Increase via punch_holes.inset_x_mm in the template config if a printer or stock runs long.
|
||||
let punch_holes_inset_x = $derived(template_cfg?.punch_holes?.inset_x_mm ?? 2);
|
||||
|
||||
// Per-slot colors: slot-specific override → shared fallback → component default.
|
||||
// When rainbow is on and no explicit fg/bg is set, use a saturated base color so
|
||||
// hue-rotate produces a full visible spectrum (gray has no hue to rotate).
|
||||
@@ -697,7 +702,10 @@ const code_to_icon: {
|
||||
<!-- Punch-out hole markers: X overlays at physical badge clip slot positions.
|
||||
Slots: 5/8in wide × 1/8in tall, 1/4in from top, 3/8in from left/right edges.
|
||||
z-index: 10 keeps markers above the header image regardless of DOM order.
|
||||
Inset ~1mm on all sides — safety margin for printer registration variance.
|
||||
Horizontal inset = punch_holes_inset_x mm per side (default 2mm) — keeps the
|
||||
marker inside the physical hole across printers and badge stock with variance.
|
||||
Vertical inset is fixed at 1mm (top and bottom). Configurable per template via
|
||||
punch_holes.inset_x_mm in the template cfg_json.
|
||||
|
||||
Rainbow sync: rainbow markers share ONE wrapper div with the hue-rotate animation.
|
||||
A single CSS animation on the wrapper drives all children simultaneously — no
|
||||
@@ -712,7 +720,7 @@ const code_to_icon: {
|
||||
class:punch_hole_rainbow_left={!punch_holes_slow_pulse}
|
||||
class:punch_hole_pulse_left={punch_holes_slow_pulse}
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); left: calc(0.375in + 1mm); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
style="top: calc(0.25in + 1mm); left: calc(0.375in + {punch_holes_inset_x}mm); width: calc(0.625in - {punch_holes_inset_x * 2}mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.5" y="0.5" width="49" height="7" fill={punch_holes_colors.left.bg} stroke={punch_holes_colors.left.fg} stroke-width="1" stroke-dasharray="4,2"/>
|
||||
<line x1="0" y1="0" x2="50" y2="8" stroke={punch_holes_colors.left.fg} stroke-width="1"/>
|
||||
@@ -721,7 +729,7 @@ const code_to_icon: {
|
||||
</div>
|
||||
<div class="punch_hole_marker punch_hole_print_rgb pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); left: calc(0.375in + 1mm); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
style="top: calc(0.25in + 1mm); left: calc(0.375in + {punch_holes_inset_x}mm); width: calc(0.625in - {punch_holes_inset_x * 2}mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs><linearGradient id="ph_rg_left" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#ff0000"/><stop offset="20%" stop-color="#ffff00"/><stop offset="40%" stop-color="#00ff00"/><stop offset="60%" stop-color="#00ffff"/><stop offset="80%" stop-color="#0000ff"/><stop offset="100%" stop-color="#ff00ff"/></linearGradient></defs>
|
||||
<rect x="0.5" y="0.5" width="49" height="7" fill="url(#ph_rg_left)" stroke="url(#ph_rg_left)" stroke-width="1" stroke-dasharray="4,2"/>
|
||||
@@ -735,7 +743,7 @@ const code_to_icon: {
|
||||
class:punch_hole_rainbow_right={!punch_holes_slow_pulse}
|
||||
class:punch_hole_pulse_right={punch_holes_slow_pulse}
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); right: calc(0.375in + 1mm); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
style="top: calc(0.25in + 1mm); right: calc(0.375in + {punch_holes_inset_x}mm); width: calc(0.625in - {punch_holes_inset_x * 2}mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.5" y="0.5" width="49" height="7" fill={punch_holes_colors.right.bg} stroke={punch_holes_colors.right.fg} stroke-width="1" stroke-dasharray="4,2"/>
|
||||
<line x1="0" y1="0" x2="50" y2="8" stroke={punch_holes_colors.right.fg} stroke-width="1"/>
|
||||
@@ -744,7 +752,7 @@ const code_to_icon: {
|
||||
</div>
|
||||
<div class="punch_hole_marker punch_hole_print_rgb pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); right: calc(0.375in + 1mm); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
style="top: calc(0.25in + 1mm); right: calc(0.375in + {punch_holes_inset_x}mm); width: calc(0.625in - {punch_holes_inset_x * 2}mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs><linearGradient id="ph_rg_right" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#ff0000"/><stop offset="20%" stop-color="#ffff00"/><stop offset="40%" stop-color="#00ff00"/><stop offset="60%" stop-color="#00ffff"/><stop offset="80%" stop-color="#0000ff"/><stop offset="100%" stop-color="#ff00ff"/></linearGradient></defs>
|
||||
<rect x="0.5" y="0.5" width="49" height="7" fill="url(#ph_rg_right)" stroke="url(#ph_rg_right)" stroke-width="1" stroke-dasharray="4,2"/>
|
||||
@@ -758,7 +766,7 @@ const code_to_icon: {
|
||||
class:punch_hole_rainbow_center={!punch_holes_slow_pulse}
|
||||
class:punch_hole_pulse_center={punch_holes_slow_pulse}
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); left: 50%; transform: translateX(-50%); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
style="top: calc(0.25in + 1mm); left: 50%; transform: translateX(-50%); width: calc(0.625in - {punch_holes_inset_x * 2}mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.5" y="0.5" width="49" height="7" fill={punch_holes_colors.center.bg} stroke={punch_holes_colors.center.fg} stroke-width="1" stroke-dasharray="4,2"/>
|
||||
<line x1="0" y1="0" x2="50" y2="8" stroke={punch_holes_colors.center.fg} stroke-width="1"/>
|
||||
@@ -767,7 +775,7 @@ const code_to_icon: {
|
||||
</div>
|
||||
<div class="punch_hole_marker punch_hole_print_rgb pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); left: 50%; transform: translateX(-50%); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
style="top: calc(0.25in + 1mm); left: 50%; transform: translateX(-50%); width: calc(0.625in - {punch_holes_inset_x * 2}mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs><linearGradient id="ph_rg_center" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="#ff0000"/><stop offset="20%" stop-color="#ffff00"/><stop offset="40%" stop-color="#00ff00"/><stop offset="60%" stop-color="#00ffff"/><stop offset="80%" stop-color="#0000ff"/><stop offset="100%" stop-color="#ff00ff"/></linearGradient></defs>
|
||||
<rect x="0.5" y="0.5" width="49" height="7" fill="url(#ph_rg_center)" stroke="url(#ph_rg_center)" stroke-width="1" stroke-dasharray="4,2"/>
|
||||
@@ -781,7 +789,7 @@ const code_to_icon: {
|
||||
{#if punch_holes_left && !punch_holes_left_rainbow}
|
||||
<div class="punch_hole_marker pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); left: calc(0.375in + 1mm); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
style="top: calc(0.25in + 1mm); left: calc(0.375in + {punch_holes_inset_x}mm); width: calc(0.625in - {punch_holes_inset_x * 2}mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.5" y="0.5" width="49" height="7" fill={punch_holes_colors.left.bg} stroke={punch_holes_colors.left.fg} stroke-width="1" stroke-dasharray="4,2"/>
|
||||
<line x1="0" y1="0" x2="50" y2="8" stroke={punch_holes_colors.left.fg} stroke-width="1"/>
|
||||
@@ -792,7 +800,7 @@ const code_to_icon: {
|
||||
{#if punch_holes_right && !punch_holes_right_rainbow}
|
||||
<div class="punch_hole_marker pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); right: calc(0.375in + 1mm); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
style="top: calc(0.25in + 1mm); right: calc(0.375in + {punch_holes_inset_x}mm); width: calc(0.625in - {punch_holes_inset_x * 2}mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.5" y="0.5" width="49" height="7" fill={punch_holes_colors.right.bg} stroke={punch_holes_colors.right.fg} stroke-width="1" stroke-dasharray="4,2"/>
|
||||
<line x1="0" y1="0" x2="50" y2="8" stroke={punch_holes_colors.right.fg} stroke-width="1"/>
|
||||
@@ -803,7 +811,7 @@ const code_to_icon: {
|
||||
{#if punch_holes_center && !punch_holes_center_rainbow}
|
||||
<div class="punch_hole_marker pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); left: 50%; transform: translateX(-50%); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
style="top: calc(0.25in + 1mm); left: 50%; transform: translateX(-50%); width: calc(0.625in - {punch_holes_inset_x * 2}mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.5" y="0.5" width="49" height="7" fill={punch_holes_colors.center.bg} stroke={punch_holes_colors.center.fg} stroke-width="1" stroke-dasharray="4,2"/>
|
||||
<line x1="0" y1="0" x2="50" y2="8" stroke={punch_holes_colors.center.fg} stroke-width="1"/>
|
||||
|
||||
Reference in New Issue
Block a user