Added the possibilty to not only make quadratic items

This commit is contained in:
2026-05-26 17:35:50 +02:00
parent be58c5941d
commit bca4fcc936
15 changed files with 371 additions and 134 deletions
+42 -9
View File
@@ -320,8 +320,16 @@
<input type="text" x-model="itemForm.name" placeholder="z.B. sticker_80" :required="!itemEditingId">
</div>
<div>
<label>Größe (mm)</label>
<input type="number" step="0.1" min="0" x-model.number="itemForm.size_mm" required>
<label>Breite (mm)</label>
<input type="number" step="0.1" min="0" x-model.number="itemForm.width_mm" required>
</div>
<div>
<label>Höhe (mm)</label>
<input type="number" step="0.1" min="0" x-model.number="itemForm.height_mm" required>
</div>
<div>
<label>Eckenradius (mm)</label>
<input type="number" step="0.1" min="0" x-model.number="itemForm.corner_radius_mm">
</div>
<div>
<label>Bleed (mm)</label>
@@ -399,7 +407,7 @@
<div class="layout-stats">
<span><strong x-text="layoutPreview.count"></strong> Items passen</span>
<span><strong x-text="layoutPreview.columns + ' × ' + layoutPreview.rows"></strong> Raster</span>
<span>Item <strong x-text="layoutPreview.footprint_width_mm.toFixed(1) + ' mm'"></strong></span>
<span>Item <strong x-text="layoutPreview.footprint_width_mm.toFixed(1) + ' × ' + layoutPreview.footprint_height_mm.toFixed(1) + ' mm'"></strong></span>
<span>Zellenabstand <strong x-text="layoutPreview.cell_width_mm.toFixed(1) + ' mm'"></strong></span>
<span>Druckfläche <strong x-text="layoutPreview.printable_width_mm.toFixed(1) + ' × ' + layoutPreview.printable_height_mm.toFixed(1) + ' mm'"></strong></span>
</div>
@@ -456,7 +464,7 @@
</div>
<div class="item-body">
<strong x-text="labelItem(it)"></strong>
<span x-text="it.spec.size_mm + ' mm · bleed ' + it.spec.bleed_mm + ' · margin ' + it.spec.margin_mm"></span>
<span x-text="itemSizeLabel(it)"></span>
<span><code x-text="it.svg_template"></code></span>
</div>
<div class="item-actions row-actions">
@@ -500,7 +508,9 @@
itemEditingId: null,
itemForm: {
name: '',
size_mm: 80,
width_mm: 80,
height_mm: 80,
corner_radius_mm: 5,
bleed_mm: 2,
margin_mm: 5,
padding_mm: 3,
@@ -723,18 +733,33 @@
defaultItemForm() {
return {
name: '',
size_mm: 80,
width_mm: 80,
height_mm: 80,
corner_radius_mm: 5,
bleed_mm: 2,
margin_mm: 5,
padding_mm: 3,
};
},
itemSizeLabel(it) {
const w = it.spec.width_mm || it.spec.size_mm;
const h = it.spec.height_mm || it.spec.size_mm;
let s = w + ' × ' + h + ' mm';
if (it.spec.corner_radius_mm) s += ' · r ' + it.spec.corner_radius_mm;
s += ' · bleed ' + it.spec.bleed_mm + ' · margin ' + it.spec.margin_mm;
return s;
},
editItem(it) {
this.itemEditingId = it.id;
const w = it.spec.width_mm || it.spec.size_mm;
const h = it.spec.height_mm || it.spec.size_mm;
this.itemForm = {
name: it.name || '',
size_mm: it.spec.size_mm,
width_mm: w,
height_mm: h,
corner_radius_mm: it.spec.corner_radius_mm || 0,
bleed_mm: it.spec.bleed_mm,
margin_mm: it.spec.margin_mm,
padding_mm: it.spec.padding_mm,
@@ -756,7 +781,9 @@
this.itemSuccess = '';
const body = {
name: this.itemForm.name,
size_mm: Number(this.itemForm.size_mm),
width_mm: Number(this.itemForm.width_mm),
height_mm: Number(this.itemForm.height_mm),
corner_radius_mm: Number(this.itemForm.corner_radius_mm) || 0,
bleed_mm: Number(this.itemForm.bleed_mm) || 0,
margin_mm: Number(this.itemForm.margin_mm) || 0,
padding_mm: Number(this.itemForm.padding_mm) || 0,
@@ -979,10 +1006,16 @@
const esc = (s) => String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;');
let items = '';
const trim = p.trim_offset_mm || 0;
const canvasW = p.canvas_width_mm || p.footprint_width_mm;
const canvasH = p.canvas_height_mm || p.footprint_height_mm;
const fpW = p.footprint_width_mm;
const fpH = p.footprint_height_mm;
for (const pos of p.positions || []) {
items += `<rect x="${pos.x_mm * scale}" y="${pos.y_mm * scale}" width="${fpW * scale}" height="${fpH * scale}" rx="3" fill="#22c55e" fill-opacity="0.35" stroke="#22c55e" stroke-width="1"/>`;
const x = pos.x_mm * scale;
const y = pos.y_mm * scale;
items += `<rect x="${x}" y="${y}" width="${canvasW * scale}" height="${canvasH * scale}" fill="none" stroke="#8b9cb3" stroke-width="0.8" stroke-dasharray="3,2"/>`;
items += `<rect x="${(pos.x_mm + trim) * scale}" y="${(pos.y_mm + trim) * scale}" width="${fpW * scale}" height="${fpH * scale}" rx="3" fill="#22c55e" fill-opacity="0.35" stroke="#22c55e" stroke-width="1"/>`;
}
const px = p.printable_x_mm * scale;
+10 -19
View File
@@ -176,14 +176,6 @@ func listItems(s *store.ItemStore) http.HandlerFunc {
}
}
type saveItemRequest struct {
Name string `json:"name"`
SizeMM float64 `json:"size_mm"`
BleedMM float64 `json:"bleed_mm"`
MarginMM float64 `json:"margin_mm"`
PaddingMM float64 `json:"padding_mm"`
}
func saveItem(s *store.ItemStore) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req saveItemRequest
@@ -191,11 +183,10 @@ func saveItem(s *store.ItemStore) http.HandlerFunc {
writeError(w, http.StatusBadRequest, err)
return
}
spec := model.ItemSpec{
SizeMM: req.SizeMM,
BleedMM: req.BleedMM,
MarginMM: req.MarginMM,
PaddingMM: req.PaddingMM,
spec, err := itemSpecFromRequest(req)
if err != nil {
writeError(w, http.StatusBadRequest, err)
return
}
saved, err := s.Create(req.Name, spec)
if err != nil {
@@ -218,12 +209,12 @@ func updateItem(s *store.ItemStore) http.HandlerFunc {
writeError(w, http.StatusBadRequest, err)
return
}
saved, err := s.Update(id, req.Name, model.ItemSpec{
SizeMM: req.SizeMM,
BleedMM: req.BleedMM,
MarginMM: req.MarginMM,
PaddingMM: req.PaddingMM,
})
spec, err := itemSpecFromRequest(req)
if err != nil {
writeError(w, http.StatusBadRequest, err)
return
}
saved, err := s.Update(id, req.Name, spec)
if err != nil {
writeError(w, http.StatusBadRequest, err)
return
+30
View File
@@ -0,0 +1,30 @@
package api
import "printer.backend/internal/model"
type saveItemRequest struct {
Name string `json:"name"`
SizeMM float64 `json:"size_mm"`
WidthMM float64 `json:"width_mm"`
HeightMM float64 `json:"height_mm"`
CornerRadiusMM float64 `json:"corner_radius_mm"`
BleedMM float64 `json:"bleed_mm"`
MarginMM float64 `json:"margin_mm"`
PaddingMM float64 `json:"padding_mm"`
}
func itemSpecFromRequest(req saveItemRequest) (model.ItemSpec, error) {
spec := model.ItemSpec{
SizeMM: req.SizeMM,
WidthMM: req.WidthMM,
HeightMM: req.HeightMM,
CornerRadiusMM: req.CornerRadiusMM,
BleedMM: req.BleedMM,
MarginMM: req.MarginMM,
PaddingMM: req.PaddingMM,
}
if err := spec.Normalize(); err != nil {
return model.ItemSpec{}, err
}
return spec, nil
}