Add RotateSeatingGroupTool for rotating table and chairs
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
import { Tool } from '../Tool';
|
||||
import { YjsDocument } from '../../crdt/YjsDocument';
|
||||
|
||||
class RotateSeatingGroupTool extends Tool {
|
||||
private selectedElements: any[] = [];
|
||||
private rotationCenter: { x: number; y: number } | null = null;
|
||||
private currentAngle: number = 0;
|
||||
|
||||
constructor(yjsDoc: YjsDocument) {
|
||||
super(yjsDoc);
|
||||
this.name = 'RotateSeatingGroupTool';
|
||||
}
|
||||
|
||||
onMouseDown(event: MouseEvent): void {
|
||||
// This tool works on selected elements, not on mouse clicks
|
||||
// The actual rotation logic would be triggered through a UI action
|
||||
// rather than a mouse click on the canvas
|
||||
}
|
||||
|
||||
onMouseMove(event: MouseEvent): void {
|
||||
// No preview needed for this tool
|
||||
}
|
||||
|
||||
onMouseUp(event: MouseEvent): void {
|
||||
// No action needed on mouse up
|
||||
}
|
||||
|
||||
onKeyUp(event: KeyboardEvent): void {
|
||||
// Handle key up events
|
||||
if (event.key === 'Escape') {
|
||||
this.reset();
|
||||
}
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this.selectedElements = [];
|
||||
this.rotationCenter = null;
|
||||
this.currentAngle = 0;
|
||||
}
|
||||
|
||||
// Set selected elements for rotation
|
||||
setSelectedElements(elements: any[]): void {
|
||||
this.selectedElements = elements;
|
||||
|
||||
// Calculate rotation center as the centroid of all selected elements
|
||||
if (elements.length > 0) {
|
||||
let totalX = 0;
|
||||
let totalY = 0;
|
||||
|
||||
elements.forEach(element => {
|
||||
totalX += element.x + element.width / 2;
|
||||
totalY += element.y + element.height / 2;
|
||||
});
|
||||
|
||||
this.rotationCenter = {
|
||||
x: totalX / elements.length,
|
||||
y: totalY / elements.length
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Rotate selected elements by a given angle
|
||||
rotateElements(angle: number): void {
|
||||
if (!this.rotationCenter || this.selectedElements.length === 0) return;
|
||||
|
||||
// Update current angle
|
||||
this.currentAngle += angle;
|
||||
|
||||
// Rotate each element around the rotation center
|
||||
this.selectedElements.forEach(element => {
|
||||
// Calculate current center of element
|
||||
const elementCenterX = element.x + element.width / 2;
|
||||
const elementCenterY = element.y + element.height / 2;
|
||||
|
||||
// Calculate vector from rotation center to element center
|
||||
const dx = elementCenterX - this.rotationCenter!.x;
|
||||
const dy = elementCenterY - this.rotationCenter!.y;
|
||||
|
||||
// Calculate new position after rotation
|
||||
const cos = Math.cos(angle);
|
||||
const sin = Math.sin(angle);
|
||||
const newX = this.rotationCenter!.x + dx * cos - dy * sin;
|
||||
const newY = this.rotationCenter!.y + dx * sin + dy * cos;
|
||||
|
||||
// Update element position (maintaining original size)
|
||||
const newElementX = newX - element.width / 2;
|
||||
const newElementY = newY - element.height / 2;
|
||||
|
||||
// In a real implementation, this would update the element in the Yjs document
|
||||
// For now, we'll just log the new position
|
||||
console.log(`Rotating element ${element.id} to (${newElementX}, ${newElementY})`);
|
||||
|
||||
// Update element in Yjs document
|
||||
this.yjsDoc.updateElement(element.id, {
|
||||
x: newElementX,
|
||||
y: newElementY
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Rotate by 90 degrees
|
||||
rotate90(): void {
|
||||
this.rotateElements(Math.PI / 2);
|
||||
}
|
||||
|
||||
// Rotate by 180 degrees
|
||||
rotate180(): void {
|
||||
this.rotateElements(Math.PI);
|
||||
}
|
||||
|
||||
// Rotate by 270 degrees
|
||||
rotate270(): void {
|
||||
this.rotateElements(Math.PI * 3 / 2);
|
||||
}
|
||||
}
|
||||
|
||||
export { RotateSeatingGroupTool };
|
||||
Reference in New Issue
Block a user