resize works, but not ideal

This commit is contained in:
2025-11-19 23:26:01 +01:00
parent 2adc151e8e
commit 4bbd92920e
2 changed files with 405 additions and 308 deletions

View File

@@ -30,6 +30,8 @@
<button id="zoom-out">-</button>
</div>
</div>
<div id="resize-handle" style="position: absolute; display: none; border: 2px dashed #4A90E2; z-index: 10;"></div>
<div class="canvas-container">
<div id="paper"></div>
</div>
@@ -55,6 +57,8 @@
});
//init paper - END
const $resizeHandle = $('#resize-handle');
// obwódka i znaczek usuwanie
function createToolsView() {
return new joint.dia.ToolsView({
@@ -69,6 +73,71 @@
});
}
function showResizeHandle(elementView) {
if (!elementView) return;
const bbox = elementView.model.getBBox();
const clientRect = paper.localToClientRect(bbox);
$resizeHandle.css({
left: clientRect.x,
top: clientRect.y,
width: clientRect.width,
height: clientRect.height
}).show();
if ($resizeHandle.data('ui-resizable')) {
$resizeHandle.resizable('destroy');
}
let originalBBox;
$resizeHandle.resizable({
handles: 'n, e, s, w, ne, se, sw, nw',
start: function(event, ui) {
if (activeElementView) {
activeElementView.hideTools();
}
originalBBox = selectedElement.getBBox();
},
resize: function(event, ui) {
if (selectedElement && originalBBox) {
const scale = paper.scale();
const newWidth = ui.size.width / scale.sx;
const newHeight = ui.size.height / scale.sy;
const newX = originalBBox.x + (ui.position.left - ui.originalPosition.left) / scale.sx;
const newY = originalBBox.y + (ui.position.top - ui.originalPosition.top) / scale.sy;
if (selectedElement.get('angle')) {
// Для повернутых фигур используем другой подход
selectedElement.resize(newWidth, newHeight, { direction: 'center' });
} else {
selectedElement.position(newX, newY);
selectedElement.resize(newWidth, newHeight);
}
}
},
stop: function(event, ui) {
if (activeElementView) {
activeElementView.showTools();
// Обновляем позицию маркера после изменения размера
showResizeHandle(activeElementView);
}
originalBBox = null;
}
});
}
function hideResizeHandle() {
if ($resizeHandle.data('ui-resizable')) {
$resizeHandle.resizable('destroy');
}
$resizeHandle.hide();
}
//create shape - START
function createRectangle(paperX, paperY) {
const rect = new joint.shapes.standard.Rectangle({
@@ -188,6 +257,7 @@
activeElementView = null;
selectedElement = null;
hideResizeHandle();
if (shapeType === 'rectangle') {
createRectangle(paperX, paperY);
@@ -211,7 +281,7 @@
//init draggable - END
function updateStatus(message) {
$('#status').text(message + ' | Zoom: ' + Math.round(zoomLevel * 100) + '%');
// $('#status').text(message + ' | Zoom: ' + Math.round(zoomLevel * 100) + '%');
}
function getViewportCenter() {
@@ -253,6 +323,7 @@
}
selectedElement = pasted;
showResizeHandle(pastedView);
updateStatus('Wklejono element');
} else {
updateStatus('Brak elementu w schowku');
@@ -260,10 +331,14 @@
}
function deleteShape() {
if (selectedElement) {
selectedElement.remove();
selectedElement = null;
activeElementView = null;
hideResizeHandle();
updateStatus('Usunięto element');
}
}
$('#btn-delete').click(function() {
deleteShape()
@@ -284,8 +359,12 @@
}
elementView.showTools();
activeElementView = elementView;
selectedElement = elementView.model;
showResizeHandle(elementView);
});
paper.on('element:pointermove', function(elementView) {
showResizeHandle(elementView);
});
let panStart = null;
@@ -300,6 +379,7 @@
activeElementView = null;
}
selectedElement = null;
hideResizeHandle();
//ruszanie caloscia
panStart = {
x: evt.clientX,
@@ -315,6 +395,7 @@
const dx = evt.clientX - panStart.x;
const dy = evt.clientY - panStart.y;
paper.translate(panStart.tx + dx, panStart.ty + dy);
showResizeHandle(activeElementView);
}
});
@@ -360,16 +441,21 @@
const minScale = 0.2;
const maxScale = 3.0;
function applyZoom(newScale, ox, oy) {
paper.scale(newScale, newScale, ox, oy);
showResizeHandle(activeElementView);
}
$('#zoom-in').click(function () {
const currentScale = paper.scale().sx;
const newScale = Math.min(maxScale, currentScale + zoomStep);
paper.scale(newScale, newScale);
applyZoom(newScale);
});
$('#zoom-out').click(function () {
const currentScale = paper.scale().sx;
const newScale = Math.max(minScale, currentScale - zoomStep);
paper.scale(newScale, newScale);
applyZoom(newScale);
});
// Zoom za pomoca kolka myszy
@@ -379,9 +465,10 @@
const zoomFactor = 0.2;
let newScale = oldScale * (1 + delta * zoomFactor);
newScale = Math.max(minScale, Math.min(maxScale, newScale));
paper.scale(newScale, newScale, x, y);
applyZoom(newScale, x, y);
});
});
</script>
</body>

View File

@@ -240,6 +240,16 @@ body {
background: #999;
}
.ui-resizable-handle {
background: #4A90E2;
border: 1px solid #ffffff;
width: 10px;
height: 10px;
border-radius: 50%;
box-shadow: 0 0 5px rgba(0,0,0,0.2);
}
/* Responsive */
@media (max-width: 768px) {
.toolbar {