@turbox3d/design-engine
Version:
Large-scale design application engine library
299 lines (298 loc) • 12.3 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = exports.MouseDealType = exports.DragStatus = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _eventManager = require("@turbox3d/event-manager");
var _math = require("@turbox3d/math");
var DragStatus;
(function (DragStatus) {
DragStatus["Ready"] = "ready";
DragStatus["Dragging"] = "dragging";
DragStatus["End"] = "end";
})(DragStatus || (exports.DragStatus = DragStatus = {}));
/**
* 当次鼠标事件(down -> move -> up)的处理类型
*/
var MouseDealType;
(function (MouseDealType) {
/**
* 作为一次 Drag 事件处理
*/
MouseDealType["Drag"] = "drag";
/**
* 作为一次 Click 事件处理
*/
MouseDealType["Click"] = "click";
/** 多点触控事件 */
MouseDealType["MultiTouch"] = "multi-touch";
/** 按压 */
MouseDealType["Press"] = "press";
})(MouseDealType || (exports.MouseDealType = MouseDealType = {}));
var MaterialDragSystem = /*#__PURE__*/function () {
function MaterialDragSystem(handler) {
var _this = this;
var maxFPS = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 60;
(0, _classCallCheck2["default"])(this, MaterialDragSystem);
this.maxFPS = 60;
/** 当前鼠标是否处于按下状态 */
this.isMouseDown = false;
/** 缓存事件池,用于多点触控 */
this.eventCache = [];
/** 双指间距 */
this.prevDiff = new _math.Vector2(-1, -1);
/** 初始的间距 */
this.startDiff = new _math.Vector2(-1, -1);
/** 双指方向 */
this.prevVector = new _math.Vector2();
/** 初始的方向 */
this.startVector = new _math.Vector2();
this.downHandler = function (eventList) {
_this.isMouseDown = true;
if (eventList.length === 1) {
_this.mouseDealType = MouseDealType.Click;
_this.dragStatus = DragStatus.Ready;
_this.mouseDownInfo = {
x: eventList[0].clientX,
y: eventList[0].clientY
};
_this.pressTimer = window.setTimeout(function () {
_this.mouseDealType = MouseDealType.Press;
_this.triggerEvent(_eventManager.InteractiveEvent.Press, eventList[0]);
}, 250);
} else if (eventList.length === 2) {
// 双指操作,rotate or pinch
window.clearTimeout(_this.pressTimer);
_this.startDiff = new _math.Vector2(Math.abs(eventList[0].clientX - eventList[1].clientX), Math.abs(eventList[0].clientY - eventList[1].clientY));
_this.startVector = new _math.Vector2(eventList[1].clientX - eventList[0].clientX, eventList[1].clientY - eventList[0].clientY);
_this.mouseDealType = MouseDealType.MultiTouch;
}
};
this.onMouseDown = function () {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return function (event) {
event.preventDefault();
_this.args = args;
_this.addEventCache(event);
_this.downHandler(_this.eventCache);
};
};
this.onTouchDown = function () {
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return function (event) {
event.preventDefault();
_this.args = args;
_this.isMouseDown = true;
_this.downHandler(Array.from(event.targetTouches || event.touches));
};
};
this.moveHandler = function (event, eventList) {
var _a, _b;
if (_this.mouseDealType === MouseDealType.MultiTouch) {
if (eventList.length === 2) {
var curDiff = new _math.Vector2(Math.abs(eventList[0].clientX - eventList[1].clientX), Math.abs(eventList[0].clientY - eventList[1].clientY));
_this.useX === undefined && (_this.useX = curDiff.x > curDiff.y);
var curVector = new _math.Vector2(eventList[1].clientX - eventList[0].clientX, eventList[1].clientY - eventList[0].clientY);
if (_this.prevDiff.x > 0 && _this.prevDiff.y > 0) {
_this.triggerEvent(_eventManager.InteractiveEvent.Pinch, event, {
scale: _this.useX ? curDiff.x / _this.startDiff.x : curDiff.y / _this.startDiff.y,
deltaScale: _this.useX ? curDiff.x / _this.prevDiff.x : curDiff.y / _this.prevDiff.y,
eventCache: eventList
});
} else {
_this.triggerEvent(_eventManager.InteractiveEvent.PinchStart, event, {
eventCache: eventList
});
}
if (_this.prevVector.x === 0 && _this.prevVector.y === 0) {
_this.triggerEvent(_eventManager.InteractiveEvent.RotateStart, event, {
eventCache: eventList
});
} else {
var degree = curVector.angleTo(_this.startVector) * _math.MathUtils.RAD2DEG;
var deltaDegree = curVector.angleTo(_this.prevVector) * _math.MathUtils.RAD2DEG;
_this.triggerEvent(_eventManager.InteractiveEvent.Rotate, event, {
rotate: degree,
deltaRotate: deltaDegree,
eventCache: eventList
});
}
_this.prevDiff = curDiff;
_this.prevVector = curVector;
}
} else if (_this.mouseDealType === MouseDealType.Drag || _this.mouseDownInfo && _this.isMouseMoved(_this.mouseDownInfo, event, 4)) {
window.clearTimeout(_this.pressTimer);
_this.mouseDealType = MouseDealType.Drag;
if (_this.dragStatus === DragStatus.Ready) {
_this.dragStatus = DragStatus.Dragging;
_this.triggerEvent(_eventManager.InteractiveEvent.DragStart, event, {
mouseDownInfo: {
x: ((_a = _this.mouseDownInfo) === null || _a === void 0 ? void 0 : _a.x) || 0,
y: ((_b = _this.mouseDownInfo) === null || _b === void 0 ? void 0 : _b.y) || 0
}
});
} else if (_this.dragStatus === DragStatus.Dragging) {
_this.triggerEvent(_eventManager.InteractiveEvent.DragMove, event);
}
}
};
this.onMouseMove = function (event) {
event.preventDefault();
if (_this.isMouseDown) {
if (_this.mouseDealType === MouseDealType.MultiTouch) {
_this.updateEventCache(event);
}
_this.moveHandler(event, _this.eventCache);
} else {
_this.triggerEvent(_eventManager.InteractiveEvent.Hover, event);
_this.triggerEvent(_eventManager.InteractiveEvent.CarriageMove, event);
}
};
this.onTouchMove = function (event) {
var eventArr = Array.from(event.targetTouches || event.touches);
if (!eventArr.length) {
return;
}
if (_this.isMouseDown) {
// 多点触控下,当前用于识别的事件先默认取第一个
if (eventArr[0].target === _this.canvas) {
event.preventDefault();
}
_this.moveHandler(eventArr[0], eventArr);
}
};
this.upHandler = function (event, eventList) {
_this.useX = undefined;
if (eventList.length === 0) {
_this.isMouseDown = false;
window.clearTimeout(_this.pressTimer);
if (_this.mouseDealType === MouseDealType.Drag) {
_this.triggerEvent(_eventManager.InteractiveEvent.DragEnd, event);
} else if (_this.mouseDealType === MouseDealType.Click) {
if (MaterialDragSystem.touchableDevice) {
_this.triggerEvent(_eventManager.InteractiveEvent.Click, event);
} else {
var tempEvent = event;
if (tempEvent.button === 0) {
_this.triggerEvent(_eventManager.InteractiveEvent.Click, event);
} else if (tempEvent.button === 2) {
_this.triggerEvent(_eventManager.InteractiveEvent.RightClick, event);
}
}
} else if (_this.mouseDealType === MouseDealType.MultiTouch) {
_this.triggerEvent(_eventManager.InteractiveEvent.PinchEnd, event, {
eventCache: eventList
});
_this.triggerEvent(_eventManager.InteractiveEvent.RotateEnd, event, {
eventCache: eventList
});
} else if (_this.mouseDealType === MouseDealType.Press) {
_this.triggerEvent(_eventManager.InteractiveEvent.PressUp, event);
}
_this.triggerEvent(_eventManager.InteractiveEvent.CarriageEnd, event);
_this.mouseDealType = undefined;
_this.dragStatus = undefined;
_this.mouseDownInfo = undefined;
_this.args = [];
} else if (_this.mouseDealType === MouseDealType.MultiTouch) {
if (eventList.length < 2) {
_this.prevDiff = new _math.Vector2(-1, -1);
_this.startDiff = new _math.Vector2(-1, -1);
_this.prevVector = new _math.Vector2();
_this.startVector = new _math.Vector2();
}
}
};
this.onMouseUp = function (event) {
event.preventDefault();
_this.removeEventCache(event);
_this.upHandler(event, _this.eventCache);
};
this.onTouchUp = function (event) {
var eventArr = Array.from(event.targetTouches || event.touches);
// 多点触控下,当前用于识别的事件先默认取第一个
if (event.changedTouches[0].target === _this.canvas) {
event.preventDefault();
}
_this.upHandler(event.changedTouches[0], eventArr);
};
this.handler = handler;
this.maxFPS = maxFPS;
this.registerListener();
}
return (0, _createClass2["default"])(MaterialDragSystem, [{
key: "isMouseMoved",
value: function isMouseMoved(mouseDownInfo, moveEvent, tolerance) {
var dx = mouseDownInfo.x - moveEvent.clientX;
var dy = mouseDownInfo.y - moveEvent.clientY;
return dx * dx + dy * dy > tolerance * tolerance;
}
}, {
key: "dispose",
value: function dispose() {
if (MaterialDragSystem.touchableDevice) {
document.removeEventListener('touchmove', this.onTouchMove);
document.removeEventListener('touchend', this.onTouchUp);
document.removeEventListener('touchcancel', this.onTouchUp);
} else {
document.removeEventListener('pointermove', this.onMouseMove);
document.removeEventListener('pointerup', this.onMouseUp);
document.removeEventListener('pointercancel', this.onMouseUp);
document.removeEventListener('pointerleave', this.onMouseUp);
}
}
}, {
key: "registerListener",
value: function registerListener() {
if (MaterialDragSystem.touchableDevice) {
document.addEventListener('touchmove', this.onTouchMove);
document.addEventListener('touchend', this.onTouchUp);
document.addEventListener('touchcancel', this.onTouchUp);
} else {
document.addEventListener('pointermove', this.onMouseMove);
document.addEventListener('pointerup', this.onMouseUp);
document.addEventListener('pointercancel', this.onMouseUp);
document.addEventListener('pointerleave', this.onMouseUp);
}
}
}, {
key: "triggerEvent",
value: function triggerEvent(e, event, extra) {
this.handler(e, event, extra);
}
}, {
key: "addEventCache",
value: function addEventCache(event) {
this.eventCache.push(event);
}
}, {
key: "removeEventCache",
value: function removeEventCache(event) {
for (var i = 0; i < this.eventCache.length; i++) {
if (this.eventCache[i].pointerId === event.pointerId) {
this.eventCache.splice(i, 1);
break;
}
}
}
}, {
key: "updateEventCache",
value: function updateEventCache(event) {
for (var i = 0; i < this.eventCache.length; i++) {
if (event.pointerId === this.eventCache[i].pointerId) {
this.eventCache[i] = event;
break;
}
}
}
}]);
}();
MaterialDragSystem.touchableDevice = 'ontouchstart' in window;
var _default = exports["default"] = MaterialDragSystem;