diff --git a/frontend/src/tools/modification/RotateSeatingGroupTool.ts b/frontend/src/tools/modification/RotateSeatingGroupTool.ts new file mode 100644 index 0000000..5163cd3 --- /dev/null +++ b/frontend/src/tools/modification/RotateSeatingGroupTool.ts @@ -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 }; \ No newline at end of file