fix: rotate/scale press-drag-release + object-center pivot
This commit is contained in:
@@ -368,10 +368,10 @@ export class InteractionEngine {
|
||||
return;
|
||||
}
|
||||
|
||||
// Move/Copy: confirm on mouseUp (drag-release)
|
||||
// Move/Copy/Rotate/Scale: confirm on mouseUp (press-drag-release)
|
||||
if (this.state.phase === 'modifying' && this.state.points.length >= 1) {
|
||||
const tool = this.state.activeTool;
|
||||
if (tool === 'move' || tool === 'copy') {
|
||||
if (tool === 'move' || tool === 'copy' || tool === 'rotate' || tool === 'scale') {
|
||||
const raw = this.getWorldCoords(e);
|
||||
const snapped = this.applySnap(raw.x, raw.y);
|
||||
const final = this.applyOrtho(snapped.x, snapped.y);
|
||||
@@ -777,10 +777,10 @@ export class InteractionEngine {
|
||||
return;
|
||||
}
|
||||
|
||||
// Move/Copy: press-drag-release (kein click-click)
|
||||
if (tool === 'move' || tool === 'copy') {
|
||||
// Move/Copy/Rotate/Scale: press-drag-release (kein click-click)
|
||||
if (tool === 'move' || tool === 'copy' || tool === 'rotate' || tool === 'scale') {
|
||||
if (this.state.phase === 'modifying' && this.state.points.length >= 1) {
|
||||
// Zweiter Klick bei move/copy — sollte nicht passieren, aber falls doch: bestätigen
|
||||
// Zweiter Klick — sollte nicht passieren bei drag-release, aber falls doch: bestätigen
|
||||
this.confirmModify(pt);
|
||||
return;
|
||||
}
|
||||
@@ -796,7 +796,7 @@ export class InteractionEngine {
|
||||
return;
|
||||
}
|
||||
|
||||
// Rotate/Scale/Mirror: click-click (Pivot + Target)
|
||||
// Mirror: click-click (zwei Punkte für die Spiegelungsachse)
|
||||
if (this.state.phase === 'modifying' && this.state.points.length >= 1) {
|
||||
this.confirmModify(pt);
|
||||
return;
|
||||
@@ -825,13 +825,17 @@ export class InteractionEngine {
|
||||
// Show preview of first selected element moved
|
||||
this.state.previewElement = moveElement(this.modifySelected[0], dx, dy);
|
||||
} else if (tool === 'rotate') {
|
||||
const angle = angleBetween(base, pt);
|
||||
this.state.previewElement = rotateElement(this.modifySelected[0], base.x, base.y, angle);
|
||||
const objCenter = { x: this.modifySelected[0].x, y: this.modifySelected[0].y };
|
||||
const startAngle = angleBetween(objCenter, base);
|
||||
const currentAngle = angleBetween(objCenter, pt);
|
||||
const rotationDelta = currentAngle - startAngle;
|
||||
this.state.previewElement = rotateElement(this.modifySelected[0], objCenter.x, objCenter.y, rotationDelta);
|
||||
} else if (tool === 'scale') {
|
||||
const dist = distance(base, pt);
|
||||
const refDist = distance(base, { x: this.modifySelected[0].x, y: this.modifySelected[0].y });
|
||||
const factor = refDist > 0 ? dist / refDist : 1;
|
||||
this.state.previewElement = scaleElement(this.modifySelected[0], base.x, base.y, factor, factor);
|
||||
const objCenter = { x: this.modifySelected[0].x, y: this.modifySelected[0].y };
|
||||
const startDist = distance(objCenter, base);
|
||||
const currentDist = distance(objCenter, pt);
|
||||
const factor = startDist > 0 ? currentDist / startDist : 1;
|
||||
this.state.previewElement = scaleElement(this.modifySelected[0], objCenter.x, objCenter.y, factor, factor);
|
||||
} else if (tool === 'mirror') {
|
||||
// Mirror preview: axis from base point to current mouse position
|
||||
this.state.previewElement = mirrorElement(this.modifySelected[0], base.x, base.y, pt.x, pt.y);
|
||||
@@ -871,14 +875,18 @@ export class InteractionEngine {
|
||||
this.onElementCreated?.({ ...copy, id: this.generateId() });
|
||||
}
|
||||
} else if (tool === 'rotate') {
|
||||
const angle = angleBetween(base, pt);
|
||||
const modified = this.modifySelected.map(el => rotateElement(el, base.x, base.y, angle));
|
||||
const objCenter = { x: this.modifySelected[0].x, y: this.modifySelected[0].y };
|
||||
const startAngle = angleBetween(objCenter, base);
|
||||
const endAngle = angleBetween(objCenter, pt);
|
||||
const rotationDelta = endAngle - startAngle;
|
||||
const modified = this.modifySelected.map(el => rotateElement(el, objCenter.x, objCenter.y, rotationDelta));
|
||||
this.onElementsModified?.(modified);
|
||||
} else if (tool === 'scale') {
|
||||
const dist = distance(base, pt);
|
||||
const refDist = distance(base, { x: this.modifySelected[0].x, y: this.modifySelected[0].y });
|
||||
const factor = refDist > 0 ? dist / refDist : 1;
|
||||
const modified = this.modifySelected.map(el => scaleElement(el, base.x, base.y, factor, factor));
|
||||
const objCenter = { x: this.modifySelected[0].x, y: this.modifySelected[0].y };
|
||||
const startDist = distance(objCenter, base);
|
||||
const endDist = distance(objCenter, pt);
|
||||
const factor = startDist > 0 ? endDist / startDist : 1;
|
||||
const modified = this.modifySelected.map(el => scaleElement(el, objCenter.x, objCenter.y, factor, factor));
|
||||
this.onElementsModified?.(modified);
|
||||
} else if (tool === 'mirror') {
|
||||
// Mirror axis: base point (first click) to current point (second click)
|
||||
|
||||
Reference in New Issue
Block a user