Erweiterungen
This commit is contained in:
Binary file not shown.
@@ -310,12 +310,68 @@ window.initProfileInvoiceGenerator = function() {
|
|||||||
return x >= ex && x <= ex + ew && y >= ey && y <= ey + eh;
|
return x >= ex && x <= ex + ew && y >= ey && y <= ey + eh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resizing state
|
||||||
|
var isResizing = false;
|
||||||
|
var resizeHandle = -1;
|
||||||
|
var resizeStart = { x: 0, y: 0, width: 0, height: 0 };
|
||||||
|
|
||||||
|
// Helper function to check if a point is on a resize handle
|
||||||
|
function getResizeHandle(x, y, el) {
|
||||||
|
if (!el || el.isStatic) return -1;
|
||||||
|
|
||||||
|
var ex = pageX + (el.x * zoomFactor);
|
||||||
|
var ey = pageY + (el.y * zoomFactor);
|
||||||
|
var ew = (el.width || 100) * zoomFactor;
|
||||||
|
var eh = (el.height || 30) * zoomFactor;
|
||||||
|
var hs = Math.max(6, 8 * zoomFactor);
|
||||||
|
var halfHs = hs / 2;
|
||||||
|
|
||||||
|
// Handle positions: 0=TL, 1=TC, 2=TR, 3=ML, 4=MR, 5=BL, 6=BC, 7=BR
|
||||||
|
var handles = [
|
||||||
|
{ x: ex - halfHs, y: ey - halfHs },
|
||||||
|
{ x: ex + ew/2 - halfHs, y: ey - halfHs },
|
||||||
|
{ x: ex + ew - halfHs, y: ey - halfHs },
|
||||||
|
{ x: ex - halfHs, y: ey + eh/2 - halfHs },
|
||||||
|
{ x: ex + ew - halfHs, y: ey + eh/2 - halfHs },
|
||||||
|
{ x: ex - halfHs, y: ey + eh - halfHs },
|
||||||
|
{ x: ex + ew/2 - halfHs, y: ey + eh - halfHs },
|
||||||
|
{ x: ex + ew - halfHs, y: ey + eh - halfHs }
|
||||||
|
];
|
||||||
|
|
||||||
|
for (var i = 0; i < handles.length; i++) {
|
||||||
|
if (x >= handles[i].x && x <= handles[i].x + hs &&
|
||||||
|
y >= handles[i].y && y <= handles[i].y + hs) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Mouse events
|
// Mouse events
|
||||||
canvas.addEventListener('mousedown', function(e) {
|
canvas.addEventListener('mousedown', function(e) {
|
||||||
var rect = canvas.getBoundingClientRect();
|
var rect = canvas.getBoundingClientRect();
|
||||||
var x = e.clientX - rect.left;
|
var x = e.clientX - rect.left;
|
||||||
var y = e.clientY - rect.top;
|
var y = e.clientY - rect.top;
|
||||||
|
|
||||||
|
// Check if clicking on a resize handle of selected element
|
||||||
|
if (selectedElement) {
|
||||||
|
var handle = getResizeHandle(x, y, selectedElement);
|
||||||
|
if (handle >= 0) {
|
||||||
|
isResizing = true;
|
||||||
|
resizeHandle = handle;
|
||||||
|
resizeStart = {
|
||||||
|
x: x,
|
||||||
|
y: y,
|
||||||
|
width: selectedElement.width || 100,
|
||||||
|
height: selectedElement.height || 30,
|
||||||
|
elemX: selectedElement.x,
|
||||||
|
elemY: selectedElement.y
|
||||||
|
};
|
||||||
|
e.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check if clicking on an element
|
// Check if clicking on an element
|
||||||
var clickedElement = null;
|
var clickedElement = null;
|
||||||
for (var i = elements.length - 1; i >= 0; i--) {
|
for (var i = elements.length - 1; i >= 0; i--) {
|
||||||
@@ -345,7 +401,62 @@ window.initProfileInvoiceGenerator = function() {
|
|||||||
var x = e.clientX - rect.left;
|
var x = e.clientX - rect.left;
|
||||||
var y = e.clientY - rect.top;
|
var y = e.clientY - rect.top;
|
||||||
|
|
||||||
if (isDragging && selectedElement) {
|
if (isResizing && selectedElement) {
|
||||||
|
// Calculate delta in base coordinates
|
||||||
|
var dx = (x - resizeStart.x) / zoomFactor;
|
||||||
|
var dy = (y - resizeStart.y) / zoomFactor;
|
||||||
|
|
||||||
|
var newWidth = resizeStart.width;
|
||||||
|
var newHeight = resizeStart.height;
|
||||||
|
var newX = resizeStart.elemX;
|
||||||
|
var newY = resizeStart.elemY;
|
||||||
|
|
||||||
|
// Handle indices: 0=TL, 1=TC, 2=TR, 3=ML, 4=MR, 5=BL, 6=BC, 7=BR
|
||||||
|
switch(resizeHandle) {
|
||||||
|
case 0: // Top-left
|
||||||
|
newWidth = Math.max(20, resizeStart.width - dx);
|
||||||
|
newHeight = Math.max(20, resizeStart.height - dy);
|
||||||
|
newX = resizeStart.elemX + (resizeStart.width - newWidth);
|
||||||
|
newY = resizeStart.elemY + (resizeStart.height - newHeight);
|
||||||
|
break;
|
||||||
|
case 1: // Top-center
|
||||||
|
newHeight = Math.max(20, resizeStart.height - dy);
|
||||||
|
newY = resizeStart.elemY + (resizeStart.height - newHeight);
|
||||||
|
break;
|
||||||
|
case 2: // Top-right
|
||||||
|
newWidth = Math.max(20, resizeStart.width + dx);
|
||||||
|
newHeight = Math.max(20, resizeStart.height - dy);
|
||||||
|
newY = resizeStart.elemY + (resizeStart.height - newHeight);
|
||||||
|
break;
|
||||||
|
case 3: // Middle-left
|
||||||
|
newWidth = Math.max(20, resizeStart.width - dx);
|
||||||
|
newX = resizeStart.elemX + (resizeStart.width - newWidth);
|
||||||
|
break;
|
||||||
|
case 4: // Middle-right
|
||||||
|
newWidth = Math.max(20, resizeStart.width + dx);
|
||||||
|
break;
|
||||||
|
case 5: // Bottom-left
|
||||||
|
newWidth = Math.max(20, resizeStart.width - dx);
|
||||||
|
newHeight = Math.max(20, resizeStart.height + dy);
|
||||||
|
newX = resizeStart.elemX + (resizeStart.width - newWidth);
|
||||||
|
break;
|
||||||
|
case 6: // Bottom-center
|
||||||
|
newHeight = Math.max(20, resizeStart.height + dy);
|
||||||
|
break;
|
||||||
|
case 7: // Bottom-right
|
||||||
|
newWidth = Math.max(20, resizeStart.width + dx);
|
||||||
|
newHeight = Math.max(20, resizeStart.height + dy);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedElement.width = snapToGrid(newWidth);
|
||||||
|
selectedElement.height = snapToGrid(newHeight);
|
||||||
|
selectedElement.x = snapToGrid(newX);
|
||||||
|
selectedElement.y = snapToGrid(newY);
|
||||||
|
|
||||||
|
draw();
|
||||||
|
notifyElementSelected(selectedElement);
|
||||||
|
} else if (isDragging && selectedElement) {
|
||||||
// Adjust mouse movement by zoom factor to get stored coordinates
|
// Adjust mouse movement by zoom factor to get stored coordinates
|
||||||
var dx = (x - dragStart.x) / zoomFactor;
|
var dx = (x - dragStart.x) / zoomFactor;
|
||||||
var dy = (y - dragStart.y) / zoomFactor;
|
var dy = (y - dragStart.y) / zoomFactor;
|
||||||
@@ -364,25 +475,47 @@ window.initProfileInvoiceGenerator = function() {
|
|||||||
draw();
|
draw();
|
||||||
notifyElementSelected(selectedElement);
|
notifyElementSelected(selectedElement);
|
||||||
} else {
|
} else {
|
||||||
// Update cursor
|
// Update cursor based on resize handles or element hover
|
||||||
var hovering = false;
|
if (selectedElement && !selectedElement.isStatic) {
|
||||||
for (var i = elements.length - 1; i >= 0; i--) {
|
var handle = getResizeHandle(x, y, selectedElement);
|
||||||
if (hitTest(x, y, elements[i])) {
|
if (handle >= 0) {
|
||||||
hovering = true;
|
// Set cursor based on handle type
|
||||||
break;
|
var cursors = ['nwse-resize', 'ns-resize', 'nesw-resize', 'ew-resize', 'ew-resize', 'nesw-resize', 'ns-resize', 'nwse-resize'];
|
||||||
|
canvas.style.cursor = cursors[handle];
|
||||||
|
} else {
|
||||||
|
var hovering = false;
|
||||||
|
for (var i = elements.length - 1; i >= 0; i--) {
|
||||||
|
if (hitTest(x, y, elements[i])) {
|
||||||
|
hovering = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
canvas.style.cursor = hovering ? 'move' : 'default';
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
var hovering = false;
|
||||||
|
for (var i = elements.length - 1; i >= 0; i--) {
|
||||||
|
if (hitTest(x, y, elements[i])) {
|
||||||
|
hovering = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
canvas.style.cursor = hovering ? 'move' : 'default';
|
||||||
}
|
}
|
||||||
canvas.style.cursor = hovering ? 'move' : 'default';
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
canvas.addEventListener('mouseup', function() {
|
canvas.addEventListener('mouseup', function() {
|
||||||
isDragging = false;
|
isDragging = false;
|
||||||
|
isResizing = false;
|
||||||
|
resizeHandle = -1;
|
||||||
canvas.style.cursor = 'default';
|
canvas.style.cursor = 'default';
|
||||||
});
|
});
|
||||||
|
|
||||||
canvas.addEventListener('mouseleave', function() {
|
canvas.addEventListener('mouseleave', function() {
|
||||||
isDragging = false;
|
isDragging = false;
|
||||||
|
isResizing = false;
|
||||||
|
resizeHandle = -1;
|
||||||
canvas.style.cursor = 'default';
|
canvas.style.cursor = 'default';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user