程式碼也在 StackBlitz
一樣把功能提到 directive 才好重覆使用
在 AppModule 宣告 RotatableDirective
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { DragDropModule } from '@angular/cdk/drag-drop'
import { AppComponent } from './app.component';
import { ResizableDirective } from './resizable.directive';
import { RotatableDirective } from './rotatable.directive';
@NgModule({
declarations: [
AppComponent,
ResizableDirective,
RotatableDirective
],
imports: [
BrowserModule,
DragDropModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
import { Directive, ElementRef, Renderer2, HostListener } from '@angular/core';
@Directive({
selector: '[rotatable]'
})
export class RotatableDirective {
private startX: number = 0;
private startY: number = 0;
private startAngle: number = 0;
constructor(private el: ElementRef, private renderer: Renderer2) {}
@HostListener('mousedown', ['$event'])
onMouseDown(event: MouseEvent) {
event.preventDefault();
this.startX = event.clientX;
this.startY = event.clientY;
const rect = this.el.nativeElement.getBoundingClientRect();
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
this.startAngle = Math.atan2(this.startY - centerY, this.startX - centerX);
const onMouseMove = (moveEvent: MouseEvent) => {
const currentX = moveEvent.clientX;
const currentY = moveEvent.clientY;
const currentAngle = Math.atan2(currentY - centerY, currentX - centerX);
const rotation = (currentAngle - this.startAngle) * (180 / Math.PI);
this.renderer.setStyle(this.el.nativeElement, 'transform', `rotate(${rotation}deg)`);
};
const onMouseUp = () => {
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
};
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
}
}
直接在div上面使用rotatable就可以了
<div class="shape-container">
<div class="shape rectangle" rotatable></div>
<div class="shape circle" rotatable></div>
<div class="shape ellipse" rotatable></div>
</div>
為了避免不知道自己在轉什麼東西,背景色改成漸層
.shape-container {
display: flex;
gap: 20px;
}
.shape {
border: 1px solid #000;
background: linear-gradient(45deg, #ff0080 0%, #00ffff 100%);
}
.rectangle {
width: 100px;
height: 50px;
}
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
}
.ellipse {
width: 150px;
height: 100px;
border-radius: 10px;
}