iT邦幫忙

2024 iThome 鐵人賽

DAY 5
1
佛心分享-SideProject30

收納規劃APP系列 第 5

Day5:ngx-moveable 實作拖曳、縮放、旋轉功能

  • 分享至 

  • xImage
  •  

要把三個功能合併的時候,決定還是用別人的套件了,時間有限
這裡實作 矩形跟圓形
官方的storyBook就有範例了

程式碼依舊在Stackblitz

首先先安裝 ngx-moveable

npm install ngx-moveable

app.module.ts

然後在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 { }

app.component.html

<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>

app.component.ts

要記得設定好你的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.scss

/* 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;
}

上一篇
Day4:旋轉功能
下一篇
Day6:ngx-moveable 變形功能之三角形處理 (同場加映Canvas)
系列文
收納規劃APP32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言