使用angular 做元素大小的拖拽,做成指令的形式。具体代码如下 1、在初始化的时候,插件文件柄元素,解决直接按照位置计算鼠标位置引起的,dom元素的拉伸过快,元素不能跟着鼠标快速拉伸的问题 2
import {
Directive,
ElementRef,
EventEmitter,
HostListener,
Input,
OnDestroy,
OnInit,
Output,
Renderer2,
} from '@angular/core';
@Directive({
selector: '[isDragResize]',
})
export class DragresizeDirective implements OnInit, OnDestroy {
@Input('isDragResize') isDragResize: boolean;
// dragDirectionRange 可拖拽的方向 八个方向,字符串形式,默认为‘all’,全部
// 当单独某个方向时可根据right,top,righttop,left,lefttop,leftbottom,bottom,rightbottom进行方向传值
@Input('dragDirectionRange') dragDirectionRange: string = 'all';
// minWidth 最小宽度
@Input('minWidth') minWidth: number;
// minHeight 最小高度
@Input('minHeight') minHeight: number;
// 是否需要定位
@Input('isPosition') isPosition: boolean;
// 单次拖拽完成事件,返回最新排序index数据
@Output() ondragEnd = new EventEmitter();
public elementLeft = 0;
public elementTop = 0;
public originClientX = 0;
public originClientY = 0;
public elementWidth = 0;
public elementHeight = 0;
public isChanging: Boolean = false;
public dragDirection: String = '';
public dragElement: any;
constructor(private el: ElementRef, private rd: Renderer2) {
}
ngOnInit() {
if (this.isDragResize) {
this.setDragHandle();
}
}
/**
* 将对应拖拽方向 插入可拖拽的dom节点
*/
setDragHandle() {
if (this.dragDirectionRange === 'all') this.dragDirectionRange = 'right,top,righttop,left,lefttop,leftbottom,bottom,rightbottom';
const dragDirectionArray = this.dragDirectionRange.split(',');
let handel = ``;
dragDirectionArray.map((direction) => {
handel += `<div class="dragHandel ${direction}Handel" drag-direction="${direction}"></div>`;
});
this.el.nativeElement.appendChild(DragresizeDirective.createDocumentFragment(handel));
}
/***
* 根据字符串模板创建dom
* @param templateString
*/
static createDocumentFragment(templateString) {
return document.createRange().createContextualFragment(templateString);
}
/**
* 元素拖拽节点的 鼠标mounseDown事件,记录初始值
* @param event
*/
@HostListener('document:mousedown', ['$event'])
onHandleMouseDown(event) {
event.preventDefault();
if (event.target.className && event.target.className.indexOf('dragHandel') > -1) {
this.dragElement = event.target.parentElement;
this.isChanging = true;
this.elementLeft = this.dragElement.offsetLeft;
this.elementTop = this.dragElement.offsetTop;
this.originClientX = event.clientX;
this.originClientY = event.clientY;
// 获取此时元素的宽高
this.elementWidth = this.dragElement.offsetWidth;
this.elementHeight = this.dragElement.offsetHeight;
this.dragDirection = event.target.getAttribute('drag-direction');
}
}
@HostListener('document:mousemove', ['$event'])
onHandleMouseMove(event) {
event.preventDefault();
if (this.isChanging) {
const clientX = event.clientX;
const clientY = event.clientY;
let width, height, top, left;
if (this.dragDirection.indexOf('right') > -1) {
width = this.elementWidth + (clientX - this.originClientX);
}
if (this.dragDirection.indexOf('top') > -1) {
top = this.elementTop + (clientY - this.originClientY);
top < 0 ? top = 0 : height = this.elementHeight + (this.originClientY - clientY);
}
if (this.dragDirection.indexOf('left') > -1) {
left = this.elementLeft - (this.originClientX - clientX);
left < 0 ? left = 0 : width = this.elementWidth + (this.originClientX - clientX);
}
if (this.dragDirection.indexOf('bottom') > -1) {
height = this.elementHeight + (clientY - this.originClientY);
}
if (width < this.minWidth) width = this.minWidth;
if (height < this.minHeight) height = this.minHeight;
if (height) this.dragElement.style.height = height + 'px';
if (width) this.dragElement.style.width = width + 'px';
if (this.isPosition) {
if (left) this.dragElement.style.left = left + 'px';
if (top) this.dragElement.style.top = top + 'px';
}
}
}
@HostListener('document:mouseup', ['$event'])
onHandleMouseUp() {
// 拖拽完成后传递宽高
if (this.isChanging) {
this.ondragEnd.emit({
width: this.dragElement.offsetWidth,
height: this.dragElement.offsetHeight,
});
}
this.isChanging = false;
}
ngOnDestroy(): void {
const dragHandleNodeList = document.querySelectorAll('.dragHandel');
for (let i = 0; i < dragHandleNodeList.length; i++) {
dragHandleNodeList[i].remove();
}
}
}