Angular中如何从对角方向反向调整div方块大小
Angular实现div左侧拖拽反向缩放方案
实现逻辑
- 将拖拽触发锚点放置在方块左侧边缘,设置东西向调整的鼠标样式,提示用户可拖拽
- 左侧拖拽缩放和默认右侧拖拽的核心差异:右侧拖拽调整尺寸时仅需修改元素宽度,元素左偏移值保持固定即可;左侧拖拽属于反向缩放,需要同步修改元素宽度和左偏移值,保证元素右侧边界位置不发生偏移,实现从左往右拉伸/收缩时方块右边缘不动、尺寸反向变化的效果
- 拖拽开始时记录三个初始值:鼠标起始横坐标、方块初始宽度、方块初始左偏移量
- 拖拽过程中计算鼠标横向移动差值,同步计算新的方块宽度和左偏移值,增加最小宽度限制,避免宽度计算为负数导致布局错乱
- 拖拽过程的事件监听放在Angular变更检测区域外执行,减少不必要的性能消耗,仅在样式值更新时触发变更检测,保证拖拽流畅度
核心代码
组件模板(html)
<div class="resizable-box" [style.width.px]="boxWidth" [style.left.px]="boxLeft"> <!-- 左侧拖拽手柄 --> <div class="left-resize-handle" (mousedown)="onResizeStart($event)"></div> <!-- 方块内部内容 --> </div>
组件逻辑(ts)
import { Component, NgZone } from '@angular/core'; @Component({ selector: 'app-resizable-box', templateUrl: './resizable-box.component.html', styleUrls: ['./resizable-box.component.css'] }) export class ResizableBoxComponent { // 方块初始状态 boxWidth = 240; boxLeft = 120; // 拖拽状态缓存 private isDragging = false; private initMouseX = 0; private initWidth = 0; private initLeft = 0; // 最小宽度限制 private readonly MIN_WIDTH = 60; constructor(private ngZone: NgZone) {} onResizeStart(e: MouseEvent): void { e.preventDefault(); this.isDragging = true; this.initMouseX = e.clientX; this.initWidth = this.boxWidth; this.initLeft = this.boxLeft; // 走zone外监听,减少变更检测开销 this.ngZone.runOutsideAngular(() => { const moveHandler = (moveE: MouseEvent) => { if (!this.isDragging) return; const deltaX = moveE.clientX - this.initMouseX; // 计算新宽度,不小于最小限制 const newWidth = Math.max(this.MIN_WIDTH, this.initWidth - deltaX); // 同步偏移左定位,保证右边界位置不变 const newLeft = this.initLeft + (this.initWidth - newWidth); this.ngZone.run(() => { this.boxWidth = newWidth; this.boxLeft = newLeft; }); }; const upHandler = () => { this.isDragging = false; document.removeEventListener('mousemove', moveHandler); document.removeEventListener('mouseup', upHandler); }; document.addEventListener('mousemove', moveHandler); document.addEventListener('mouseup', upHandler); }); } }
组件样式(css)
.resizable-box { position: absolute; top: 80px; height: 200px; background: #f5f5f5; border: 1px solid #dcdcdc; border-radius: 4px; } .left-resize-handle { position: absolute; left: 0; top: 0; width: 8px; height: 100%; cursor: ew-resize; /* 向左偏移4px,扩大拖拽热区,不占用方块内部显示空间 */ transform: translateX(-4px); background: transparent; }
内容的提问来源于stack exchange,提问作者Med Anoir Bday
相关产品推荐
相关产品推荐

