要把三個功能合併的時候,決定還是用別人的套件了,時間有限
這裡實作 矩形跟圓形
官方的storyBook就有範例了
程式碼依舊在Stackblitz
首先先安裝 ngx-moveable
npm install ngx-moveable
然後在app.module.ts引入
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { DragDropModule } from '@angular/cdk/drag-drop'
import { AppComponent } from './app.component';
import { NgxMoveableModule } from 'ngx-moveable';
import { TriangleCanvasComponent } from './triangle-canvas/triangle-canvas.component';
import { TriangleShapeComponent } from './triangle-shape/triangle-shape.component';
import { RoundedRectangleComponent } from './rounded-rectangle/rounded-rectangle.component';
@NgModule({
declarations: [
AppComponent,
// TriangleShapeComponent,
// RoundedRectangleComponent,
],
imports: [
BrowserModule,
NgxMoveableModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
<div class="container">
<div class="target" #square>Move me!</div>
<ngx-moveable
#moveableRef
[target]="square"
[draggable]="draggable"
[throttleDrag]="throttleDrag"
[edgeDraggable]="edgeDraggable"
[startDragRotate]="startDragRotate"
[throttleDragRotate]="throttleDragRotate"
[resizable]="resizable"
[keepRatio]="keepRatio"
[throttleResize]="throttleResize"
[renderDirections]="renderDirections"
[rotatable]="rotatable"
[throttleRotate]="throttleRotate"
[rotationPosition]="rotationPosition"
(drag)="onDrag($event,'square')"
(resize)="onResize($event,'square')"
(rotate)="onRotate($event)"
></ngx-moveable>
<div class="target4" style="border-radius: 5px;" #roundedRectangle>圓角</div>
<ngx-moveable
[target]="'.target4'"
[roundable]="true"
(round)="onRound$2($event)"
></ngx-moveable>
</div>
要記得設定好你的target
主要使用的是這三個事件綁定 (drag)="onDrag($event)"、 (resize)="onResize($event)"、 (rotate)="onRotate($event)",可以對圖形做操作
其他的屬性綁定屬於控制操作項,像是能不能拖曳 draggable
,控制點方位 renderDirections
import { Component, ViewChild, ElementRef } from '@angular/core';
import { NgxMoveableComponent } from 'ngx-moveable';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
@ViewChild('square') square!: ElementRef<HTMLDivElement>;
@ViewChild('roundedRectangle') roundedRectangle!: ElementRef<HTMLDivElement>;
@ViewChild("moveableRef") moveableRef!: NgxMoveableComponent;
svgWidth = 400;
svgHeight = 400;
draggable: any = true;
resizable: any = true;
keepRatio: any = false;
edgeDraggable: any = false;
throttleResize: any = 1;
startDragRotate: any = 0;
renderDirections: any = ["nw", "n", "ne", "w", "e", "sw", "s", "se"];
rotatable: any = true;
throttleRotate: any = 0;
rotationPosition: any = "top";
throttleDragRotate: any = 0;
throttleDrag: any = 1;
onDrag(e: { target: { style: { transform: any; }; }; transform: any; }, type: 'square' | 'triangle') {
switch (type) {
case 'square':
e.target.style.transform = e.transform;
break;
default:
break;
}
}
onResize(e: {
target: {
style: {
borderBottom: string;
borderLeft: string;
borderRight: string; width: string; height: string; transform: any;
};
}; width: any; height: any; drag: { transform: any; };
}, type: 'square' | 'triangle') {
switch (type) {
case 'square':
e.target.style.width = `${e.width}px`;
e.target.style.height = `${e.height}px`;
e.target.style.transform = e.drag.transform;
break;
default:
break;
}
}
onRotate(e: { target: { style: { transform: any; }; }; drag: { transform: any; }; }) {
e.target.style.transform = e.drag.transform;
}
onRound$2(e: { borderRadius: any; target: { style: { borderRadius: any; }; }; }) {
e.target.style.borderRadius = e.borderRadius;
}
}
/* app.component.css */
.container {
position: relative;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: #f0f0f0;
}
.target {
width: 200px;
height: 200px;
background-color: #4caf50;
color: white;
display: flex;
justify-content: center;
align-items: center;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
cursor: move;
position: absolute;
}
.target4 {
position: absolute;
width: 100px;
height: 100px;
top: 150px;
left: 100px;
line-height: 100px;
text-align: center;
background: #ee8;
color: #333;
font-weight: bold;
border: 1px solid #333;
box-sizing: border-box;
}