Erweiterungen

This commit is contained in:
2026-02-13 13:33:27 +01:00
parent 0d8b455031
commit ceffef2332
3 changed files with 120 additions and 23 deletions

Binary file not shown.

View File

@@ -45,6 +45,9 @@ window.initProfileInvoiceGenerator = function() {
var elementStart = { x: 0, y: 0 }; var elementStart = { x: 0, y: 0 };
var gridSize = 5; var gridSize = 5;
// Image cache to prevent flickering during resize
var imageCache = {};
// Page dimensions // Page dimensions
var padding = 10; var padding = 10;
var pageX, pageY, pageWidth, pageHeight; var pageX, pageY, pageWidth, pageHeight;
@@ -167,25 +170,47 @@ window.initProfileInvoiceGenerator = function() {
ctx.stroke(); ctx.stroke();
} else if (el.type === 'image') { } else if (el.type === 'image') {
if (el.imageData) { if (el.imageData) {
// Draw the uploaded image with aspect ratio preserved // Check if image is already cached
var img = new Image(); if (imageCache[el.imageData]) {
img.onload = function() { // Use cached image for flicker-free rendering
var img = imageCache[el.imageData];
// Calculate dimensions to maintain aspect ratio (object-fit: contain) // Calculate dimensions to maintain aspect ratio (object-fit: contain)
var imgAspect = img.width / img.height; var imgAspect = img.width / img.height;
var boxAspect = w / h; var boxAspect = w / h;
var drawW, drawH, drawX, drawY; var drawW, drawH, drawX, drawY;
if (imgAspect > boxAspect) { if (imgAspect > boxAspect) {
// Image is wider than box - fit to width
drawW = w; drawW = w;
drawH = w / imgAspect; drawH = w / imgAspect;
drawX = x; drawX = x;
drawY = y + (h - drawH) / 2; // Center vertically drawY = y + (h - drawH) / 2;
} else { } else {
// Image is taller than box - fit to height
drawW = h * imgAspect; drawW = h * imgAspect;
drawH = h; drawH = h;
drawX = x + (w - drawW) / 2; // Center horizontally drawX = x + (w - drawW) / 2;
drawY = y;
}
ctx.drawImage(img, drawX, drawY, drawW, drawH);
} else {
// Load and cache the image
var img = new Image();
img.onload = function() {
imageCache[el.imageData] = img;
// Calculate dimensions to maintain aspect ratio
var imgAspect = img.width / img.height;
var boxAspect = w / h;
var drawW, drawH, drawX, drawY;
if (imgAspect > boxAspect) {
drawW = w;
drawH = w / imgAspect;
drawX = x;
drawY = y + (h - drawH) / 2;
} else {
drawW = h * imgAspect;
drawH = h;
drawX = x + (w - drawW) / 2;
drawY = y; drawY = y;
} }
@@ -196,6 +221,7 @@ window.initProfileInvoiceGenerator = function() {
} }
}; };
img.src = el.imageData; img.src = el.imageData;
}
} else { } else {
// Draw placeholder // Draw placeholder
ctx.fillStyle = '#f0f0f0'; ctx.fillStyle = '#f0f0f0';
@@ -799,10 +825,41 @@ window.initProfileInvoiceGenerator = function() {
}; };
// Get canvas data // Get canvas data
// Helper functions for percentage conversion
function toPercentX(value) {
return (value / basePageWidth * 100).toFixed(2);
}
function toPercentY(value) {
return (value / basePageHeight * 100).toFixed(2);
}
function fromPercentX(percent) {
return Math.round(parseFloat(percent) / 100 * basePageWidth);
}
function fromPercentY(percent) {
return Math.round(parseFloat(percent) / 100 * basePageHeight);
}
window.getProfileCanvasData = function() { window.getProfileCanvasData = function() {
saveState(); saveState();
// Convert pixel values to percentages for storage
var elementsWithPercent = elements.map(function(el) {
return { return {
elements: elements id: el.id,
type: el.type,
text: el.text,
xPercent: toPercentX(el.x),
yPercent: toPercentY(el.y),
widthPercent: toPercentX(el.width),
heightPercent: toPercentY(el.height),
fontSize: el.fontSize,
fontStyle: el.fontStyle,
color: el.color,
isStatic: el.isStatic,
imageData: el.imageData
};
});
return {
elements: elementsWithPercent
}; };
}; };
@@ -868,6 +925,21 @@ window.initProfileInvoiceGenerator = function() {
elementCounter++; elementCounter++;
el.id = 'element-' + elementCounter; el.id = 'element-' + elementCounter;
} }
// Convert percentages to pixels if they exist, otherwise use legacy pixel values
if (el.xPercent !== undefined) {
el.x = fromPercentX(el.xPercent);
}
if (el.yPercent !== undefined) {
el.y = fromPercentY(el.yPercent);
}
if (el.widthPercent !== undefined) {
el.width = fromPercentX(el.widthPercent);
}
if (el.heightPercent !== undefined) {
el.height = fromPercentY(el.heightPercent);
}
elements.push(el); elements.push(el);
}); });

View File

@@ -273,19 +273,44 @@ public class CustomerInvoiceService {
for (com.fasterxml.jackson.databind.JsonNode element : elements) { for (com.fasterxml.jackson.databind.JsonNode element : elements) {
String type = element.has("type") ? element.get("type").asText("text") : "text"; String type = element.has("type") ? element.get("type").asText("text") : "text";
String text = element.has("text") ? element.get("text").asText("") : ""; String text = element.has("text") ? element.get("text").asText("") : "";
double x = element.has("x") ? element.get("x").asDouble(0) : 0;
double y = element.has("y") ? element.get("y").asDouble(0) : 0; // Use percentage values if available, otherwise fall back to legacy pixel values
double width = element.has("width") ? element.get("width").asDouble(150) : 150; double xPercent, yPercent, widthPercent, heightPercent;
double height = element.has("height") ? element.get("height").asDouble(30) : 30; if (element.has("xPercent")) {
xPercent = element.get("xPercent").asDouble(0);
} else {
// Legacy: convert pixels to percent
double x = element.get("x").asDouble(0);
xPercent = x / 595.0 * 100;
}
if (element.has("yPercent")) {
yPercent = element.get("yPercent").asDouble(0);
} else {
double y = element.get("y").asDouble(0);
yPercent = y / 842.0 * 100;
}
if (element.has("widthPercent")) {
widthPercent = element.get("widthPercent").asDouble(15);
} else {
double width = element.get("width").asDouble(150);
widthPercent = width / 595.0 * 100;
}
if (element.has("heightPercent")) {
heightPercent = element.get("heightPercent").asDouble(3);
} else {
double height = element.get("height").asDouble(30);
heightPercent = height / 842.0 * 100;
}
int fontSize = element.has("fontSize") ? element.get("fontSize").asInt(14) : 14; int fontSize = element.has("fontSize") ? element.get("fontSize").asInt(14) : 14;
String fontStyle = element.has("fontStyle") ? element.get("fontStyle").asText("") : ""; String fontStyle = element.has("fontStyle") ? element.get("fontStyle").asText("") : "";
String color = element.has("color") ? element.get("color").asText("#333333") : "#333333"; String color = element.has("color") ? element.get("color").asText("#333333") : "#333333";
// Convert canvas coordinates to mm (assuming 96 DPI) // Convert percentages to mm (A4 is 210mm x 297mm)
double mmX = x * 25.4 / 96; double mmX = xPercent / 100.0 * 210.0;
double mmY = y * 25.4 / 96; double mmY = yPercent / 100.0 * 297.0;
double mmWidth = width * 25.4 / 96; double mmWidth = widthPercent / 100.0 * 210.0;
double mmHeight = height * 25.4 / 96; double mmHeight = heightPercent / 100.0 * 297.0;
htmlBuilder.append("<div class='element ").append(type).append("' "); htmlBuilder.append("<div class='element ").append(type).append("' ");
htmlBuilder.append("style='"); htmlBuilder.append("style='");