Files
oops-plugin-framework/assets/core/extension/NodeDragExt.ts
2024-03-04 14:46:13 +08:00

185 lines
6.8 KiB
TypeScript

import { EventTouch, Node, Vec2, js, v3 } from "cc";
import { DEV, EDITOR } from "cc/env";
/** 节点拖拽功能 */
if (!EDITOR) {
//@ts-ignore
if (!Node.prototype["__$cc-node-drag-extension$__"]) {
//@ts-ignore
Node.prototype["__$cc-node-drag-extension$__"] = true;
let _DragEvent = {
DRAG_START: "drag_start",
DRAG_MOVE: "drag_move",
DRAG_END: "drag_end"
}
js.mixin(Node, {
DragEvent: _DragEvent
});
//---------------- Node 添加 拖拽属性 ----------------
js.mixin(Node.prototype, {
_draggable: false,
_dragging: false,
_dragTesting: false,
_dragStartPoint: null,
initDrag: function () {
if (this._draggable) {
this.on(Node.EventType.TOUCH_START, this.onTouchBegin_0, this);
this.on(Node.EventType.TOUCH_MOVE, this.onTouchMove_0, this);
this.on(Node.EventType.TOUCH_END, this.onTouchEnd_0, this);
this.on(Node.EventType.TOUCH_CANCEL, this.onTouchCancel_0, this);
}
else {
this.off(Node.EventType.TOUCH_START, this.onTouchBegin_0, this);
this.off(Node.EventType.TOUCH_MOVE, this.onTouchMove_0, this);
this.off(Node.EventType.TOUCH_END, this.onTouchEnd_0, this);
this.off(Node.EventType.TOUCH_CANCEL, this.onTouchCancel_0, this);
}
},
onTouchBegin_0: function (event: EventTouch) {
if (this._dragStartPoint == null) {
this._dragStartPoint = new Vec2();
}
DEV && console.log(`cc-node-drag-extension-> onTouchBegin_0 ${this.name}`);
// event.preventSwallow = true;
let pos = event.getUILocation();
this._dragStartPoint.set(pos);
this._dragTesting = true;
},
onTouchMove_0: function (event: EventTouch) {
if (!this._dragging && this._draggable && this._dragTesting) {
let sensitivity = 10;
let pos = event.getUILocation();
if (Math.abs(this._dragStartPoint.x - pos.x) < sensitivity
&& Math.abs(this._dragStartPoint.y - pos.y) < sensitivity) {
return;
}
// event.preventSwallow = true;
this._dragging = true;
this._dragTesting = false;
this.emit(Node.DragEvent.DRAG_START, event);
}
if (this._dragging) {
let delta = event.getUIDelta();
// /** 这里除以 世界缩放,在有缩放的时候拖拽不至于很怪 */
// this.position = this.position.add(v3(delta.x / this.worldScale.x, delta.y / this.worldScale.y, 0));
this.position = this.position.add(v3(delta.x, delta.y, 0));
this.emit(Node.DragEvent.DRAG_MOVE, event);
}
},
onTouchEnd_0: function (event: EventTouch) {
if (this._dragging) {
this._dragging = false;
this.emit(Node.DragEvent.DRAG_END, event);
}
DEV && console.log(`cc-node-drag-extension-> onTouchEnd_0 ${this.name}, _dragging: ${this._dragging}`);
},
onTouchCancel_0: function (event: EventTouch) {
if (this._dragging) {
this._dragging = false;
this.emit(Node.DragEvent.DRAG_END, event);
}
DEV && console.log(`cc-node-drag-extension-> onTouchCancel_0 ${this.name}, _dragging: ${this._dragging}`);
},
startDrag: function () {
//此节点是否在场景中激活
if (!this.activeInHierarchy) {
return;
}
this.dragBegin();
},
dragBegin: function () {
this._dragging = true;
this._dragTesting = true;
this.on(Node.EventType.TOUCH_MOVE, this.onTouchMove_0, this);
this.on(Node.EventType.TOUCH_END, this.onTouchEnd_0, this);
this.on(Node.EventType.TOUCH_CANCEL, this.onTouchCancel_0, this);
},
dragEnd: function () {
if (this._dragging) {
this._dragTesting = false;
this._dragging = false;
}
},
// 停止拖拽
stopDrag: function () {
this.dragEnd();
},
// 移除 touch 事件
removeDragEvent: function () {
this.off(Node.EventType.TOUCH_START, this.onTouchBegin_0, this);
this.off(Node.EventType.TOUCH_MOVE, this.onTouchMove_0, this);
this.off(Node.EventType.TOUCH_END, this.onTouchEnd_0, this);
this.off(Node.EventType.TOUCH_CANCEL, this.onTouchCancel_0, this);
}
});
// 如果 node 设置 node.draggable = true, 则启用 拖拽
Object.defineProperty(Node.prototype, "draggable", {
get: function () {
return this._draggable;
},
set: function (value) {
if (this._draggable != value) {
this._draggable = value;
this.initDrag();
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(Node.prototype, "dragTesting", {
get: function () {
return this._dragTesting;
},
set: function (value) {
if (this._dragTesting != value) {
this._dragTesting = value;
}
},
enumerable: true,
configurable: true
});
//---------------- Node 添加 拖拽属性 ---------------- end
}
}
declare module "cc" {
// 这里使用 interface 进行扩展,如果使用 class 则会与现有的 d.ts 有冲突
export interface Node {
/** 是否启动拖拽 - true为启动 */
draggable: boolean;
/** 开始拖拽 */
startDrag(): void;
/** 停止拖拽 */
stopDrag(): void;
/** 移除拖拽事件 */
removeDragEvent(): void;
}
export namespace Node {
/** 支持的拖拽事件 */
export class DragEvent {
/** 拖拽开始事件 */
static DRAG_START: string;
/** 拖拽移动事件 */
static DRAG_MOVE: string;
/** 拖拽结束事件 */
static DRAG_END: string;
}
}
}