@turbox3d/event-manager
Version:
Large-scale productivity application event management library
391 lines (390 loc) • 19 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.InteractiveController = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _shared = require("@turbox3d/shared");
var _index = require("./listener/index");
var _type = require("./listener/type");
var _sceneEvent = require("./sceneEvent");
var InteractiveController = exports.InteractiveController = /*#__PURE__*/function () {
function InteractiveController(option) {
var _this = this;
(0, _classCallCheck2["default"])(this, InteractiveController);
/** 交互对象的配置 */
this.interactiveConfig = new Map();
/** 最大帧率限制 */
this.maxFPS = 60;
/**
* 更新视图对象的交互配置
*
* @param view 视图对象
* @param config 交互配置。该参数不传时认为该对象无法交互
*/
this.updateInteractiveObject = function (view, config) {
if (config) {
_this.interactiveConfig.set(view, config);
} else {
_this.interactiveConfig["delete"](view);
}
};
/** 更新视口信息 */
this.updateViewportInfo = function (viewport) {
_this.viewport = viewport;
_this.interactiveListener.updateViewportInfo(viewport);
};
/**
* 用于给外部发起一次点击拾取
* @param point 是相对于 canvas 左上角的点击位置
*/
this.hitTarget = function (point) {
var originalPoint = _this.revisePointByViewPort(point);
var _this$getHitTargetOri = _this.getHitTargetOriginal(originalPoint, _this.container, _this.interactiveConfig, 'isClickable'),
target = _this$getHitTargetOri.target;
if (target) {
var config = _this.interactiveConfig.get(target);
if (config && config.getViewEntity) {
return config.getViewEntity();
}
}
return undefined;
};
this.onClick = function (event) {
var _this$hitTargetHandle = _this.hitTargetHandler(event, 'isClickable'),
target = _this$hitTargetHandle.target;
if (target) {
_this.lastClickTarget = target;
var config = _this.interactiveConfig.get(target);
if (config && config.isClickable) {
if (config.onClick) {
config.onClick(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
}
return;
}
}
_this.lastClickTarget = undefined;
// 点击在画布上,没有命中任何目标
_this.canvasHandlers.onClick(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
};
this.onDBClick = function (event) {
// 双击事件使用上次 click 命中的目标,避免重复计算
if (_this.lastClickTarget) {
var config = _this.interactiveConfig.get(_this.lastClickTarget);
if (config && config.isClickable && config.onDBClick) {
config.onDBClick(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
}
}
};
this.onRightClick = function (event) {
var _this$hitTargetHandle2 = _this.hitTargetHandler(event, 'isClickable'),
target = _this$hitTargetHandle2.target;
if (target) {
var config = _this.interactiveConfig.get(target);
if (config && config.onRightClick) {
config.onRightClick(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
return;
}
}
_this.canvasHandlers.onRightClick(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
};
this.onDragStart = function (event, extra) {
var _this$hitTargetHandle3 = _this.hitTargetHandler(event, 'isDraggable'),
target = _this$hitTargetHandle3.target;
if (target) {
var config = _this.interactiveConfig.get(target);
if (config && config.isDraggable && config.onDragStart) {
_this.dragTarget = target;
config.onDragStart(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint, extra));
}
return;
}
_this.canvasHandlers.onDragStart(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint, extra));
};
this.onDragMove = function (event) {
if (_this.dragTarget) {
var config = _this.interactiveConfig.get(_this.dragTarget);
if (config && config.isDraggable && config.onDragMove) {
config.onDragMove(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
}
return;
}
_this.canvasHandlers.onDragMove(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
};
this.onDragEnd = function (event) {
if (_this.dragTarget) {
var config = _this.interactiveConfig.get(_this.dragTarget);
if (config && config.isDraggable && config.onDragEnd) {
config.onDragEnd(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
}
_this.dragTarget = undefined;
return;
}
_this.canvasHandlers.onDragEnd(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
};
this.onPinchStart = function (event, extra) {
var _this$hitTargetHandle4 = _this.hitTargetHandler(event, 'isPinchable'),
target = _this$hitTargetHandle4.target;
if (target) {
var config = _this.interactiveConfig.get(target);
if (config && config.isPinchable && config.onPinchStart) {
_this.dragTarget = target;
config.onPinchStart(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint, extra));
}
return;
}
_this.canvasHandlers.onPinchStart(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint, extra));
};
this.onPinch = function (event, extra) {
if (_this.dragTarget) {
var config = _this.interactiveConfig.get(_this.dragTarget);
if (config && config.isPinchable && config.onPinch) {
config.onPinch(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint, extra));
}
return;
}
_this.canvasHandlers.onPinch(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint, extra));
};
this.onPinchEnd = function (event, extra) {
if (_this.dragTarget) {
var config = _this.interactiveConfig.get(_this.dragTarget);
if (config && config.isPinchable && config.onPinchEnd) {
config.onPinchEnd(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint, extra));
}
_this.dragTarget = undefined;
return;
}
_this.canvasHandlers.onPinchEnd(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint, extra));
};
this.onRotateStart = function (event, extra) {
var _this$hitTargetHandle5 = _this.hitTargetHandler(event, 'isRotatable'),
target = _this$hitTargetHandle5.target;
if (target) {
var config = _this.interactiveConfig.get(target);
if (config && config.isRotatable && config.onRotateStart) {
_this.dragTarget = target;
config.onRotateStart(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint, extra));
}
return;
}
_this.canvasHandlers.onRotateStart(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint, extra));
};
this.onRotate = function (event, extra) {
if (_this.dragTarget) {
var config = _this.interactiveConfig.get(_this.dragTarget);
if (config && config.isRotatable && config.onRotate) {
config.onRotate(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint, extra));
}
return;
}
_this.canvasHandlers.onRotate(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint, extra));
};
this.onRotateEnd = function (event, extra) {
if (_this.dragTarget) {
var config = _this.interactiveConfig.get(_this.dragTarget);
if (config && config.isRotatable && config.onRotateEnd) {
config.onRotateEnd(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint, extra));
}
_this.dragTarget = undefined;
return;
}
_this.canvasHandlers.onRotateEnd(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint, extra));
};
this.onPress = function (event) {
var _this$hitTargetHandle6 = _this.hitTargetHandler(event, 'isPressable'),
target = _this$hitTargetHandle6.target;
if (target) {
var config = _this.interactiveConfig.get(target);
if (config && config.isPressable) {
if (config.onPress) {
config.onPress(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
}
return;
}
}
_this.canvasHandlers.onPress(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
};
this.onPressUp = function (event) {
var _this$hitTargetHandle7 = _this.hitTargetHandler(event, 'isPressable'),
target = _this$hitTargetHandle7.target;
if (target) {
var config = _this.interactiveConfig.get(target);
if (config && config.isPressable) {
if (config.onPressUp) {
config.onPressUp(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
}
return;
}
}
_this.canvasHandlers.onPressUp(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
};
this.onCarriageMove = function (event) {
_this.canvasHandlers.onPointerMove(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
};
this.onCarriageEnd = function (event) {
_this.canvasHandlers.onPointerUp(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
};
this.onHover = function (event) {
var _this$hitTargetHandle8 = _this.hitTargetHandler(event, 'isHoverable'),
target = _this$hitTargetHandle8.target;
if (target) {
// 如果 hover 目标产生了变更
if (_this.hoverTarget) {
if (target !== _this.hoverTarget) {
// 对上一次目标执行 hoverOut
_this.onHoverOut(_this.hoverTarget, event);
// 对新目标执行 hoverIn
_this.onHoverIn(target, event);
}
} else {
_this.onHoverIn(target, event);
}
} else if (_this.hoverTarget) {
_this.onHoverOut(_this.hoverTarget, event);
_this.hoverTarget = undefined;
}
};
this.onWheel = function (event) {
_this.canvasHandlers.onWheel(_sceneEvent.SceneEvent.create(event, _this.getCoordinateCtrl, _this.hitTargetOriginalByPoint));
};
this.renderer = option.renderer;
this.container = option.container;
this.canvasHandlers = option.canvasHandler;
this.viewport = option.viewport;
this.coordinateType = option.coordinateType;
this.getCoordinateCtrl = option.getCoordinateCtrl;
this.getHitTargetOriginal = option.getHitTargetOriginal;
this.maxFPS = option.maxFPS;
}
/**
* 对画布进行交互事件监听
*
* @param canvas
*/
return (0, _createClass2["default"])(InteractiveController, [{
key: "startListener",
value: function startListener() {
var Click = _type.InteractiveEvent.Click,
DBClick = _type.InteractiveEvent.DBClick,
RightClick = _type.InteractiveEvent.RightClick,
DragStart = _type.InteractiveEvent.DragStart,
DragMove = _type.InteractiveEvent.DragMove,
DragEnd = _type.InteractiveEvent.DragEnd,
Hover = _type.InteractiveEvent.Hover,
CarriageMove = _type.InteractiveEvent.CarriageMove,
CarriageEnd = _type.InteractiveEvent.CarriageEnd,
Wheel = _type.InteractiveEvent.Wheel,
PinchStart = _type.InteractiveEvent.PinchStart,
Pinch = _type.InteractiveEvent.Pinch,
PinchEnd = _type.InteractiveEvent.PinchEnd,
RotateStart = _type.InteractiveEvent.RotateStart,
Rotate = _type.InteractiveEvent.Rotate,
RotateEnd = _type.InteractiveEvent.RotateEnd,
Press = _type.InteractiveEvent.Press,
PressUp = _type.InteractiveEvent.PressUp;
this.interactiveListener = _index.InteractiveListener.create(this.renderer, this.viewport, this.coordinateType);
this.interactiveListener.registerListener();
this.interactiveListener.addEventListener(Click, this.onClick).addEventListener(DBClick, this.onDBClick).addEventListener(RightClick, this.onRightClick).addEventListener(DragStart, this.onDragStart).addEventListener(DragMove, (0, _shared.throttleInAFrame)(this.onDragMove, _shared.TaskPriority.UserAction, this.maxFPS)).addEventListener(DragEnd, this.onDragEnd).addEventListener(Hover, (0, _shared.throttleInAFrame)(this.onHover, _shared.TaskPriority.UserAction, this.maxFPS)).addEventListener(CarriageMove, (0, _shared.throttleInAFrame)(this.onCarriageMove, _shared.TaskPriority.UserAction, this.maxFPS)).addEventListener(CarriageEnd, this.onCarriageEnd).addEventListener(Wheel, (0, _shared.throttleInAFrame)(this.onWheel, _shared.TaskPriority.UserAction, this.maxFPS)).addEventListener(PinchStart, this.onPinchStart).addEventListener(Pinch, (0, _shared.throttleInAFrame)(this.onPinch, _shared.TaskPriority.UserAction, this.maxFPS)).addEventListener(PinchEnd, this.onPinchEnd).addEventListener(RotateStart, this.onRotateStart).addEventListener(Rotate, (0, _shared.throttleInAFrame)(this.onRotate, _shared.TaskPriority.UserAction, this.maxFPS)).addEventListener(RotateEnd, this.onRotateEnd).addEventListener(Press, this.onPress).addEventListener(PressUp, this.onPressUp);
}
/**
* 取消所有监听的交互事件
* @param canvas
*/
}, {
key: "removeAllListener",
value: function removeAllListener() {
var Click = _type.InteractiveEvent.Click,
DBClick = _type.InteractiveEvent.DBClick,
RightClick = _type.InteractiveEvent.RightClick,
DragStart = _type.InteractiveEvent.DragStart,
DragMove = _type.InteractiveEvent.DragMove,
DragEnd = _type.InteractiveEvent.DragEnd,
Hover = _type.InteractiveEvent.Hover,
CarriageMove = _type.InteractiveEvent.CarriageMove,
CarriageEnd = _type.InteractiveEvent.CarriageEnd,
Wheel = _type.InteractiveEvent.Wheel,
PinchStart = _type.InteractiveEvent.PinchStart,
Pinch = _type.InteractiveEvent.Pinch,
PinchEnd = _type.InteractiveEvent.PinchEnd,
RotateStart = _type.InteractiveEvent.RotateStart,
Rotate = _type.InteractiveEvent.Rotate,
RotateEnd = _type.InteractiveEvent.RotateEnd,
Press = _type.InteractiveEvent.Press,
PressUp = _type.InteractiveEvent.PressUp;
this.interactiveListener.removeEventListener(Click, this.onClick).removeEventListener(DBClick, this.onDBClick).removeEventListener(RightClick, this.onRightClick).removeEventListener(DragStart, this.onDragStart).removeEventListener(DragMove, this.onDragMove).removeEventListener(DragEnd, this.onDragEnd).removeEventListener(Hover, this.onHover).removeEventListener(CarriageMove, this.onCarriageMove).removeEventListener(CarriageEnd, this.onCarriageEnd).removeEventListener(Wheel, this.onWheel).removeEventListener(PinchStart, this.onPinchStart).removeEventListener(Pinch, this.onPinch).removeEventListener(PinchEnd, this.onPinchEnd).removeEventListener(RotateStart, this.onRotateStart).removeEventListener(Rotate, this.onRotate).removeEventListener(RotateEnd, this.onRotateEnd).removeEventListener(Press, this.onPress).removeEventListener(PressUp, this.onPressUp);
this.interactiveListener.dispose();
}
/**
* 获取本次鼠标事件的交互对象
*/
}, {
key: "hitTargetHandler",
value: function hitTargetHandler(event, type) {
var originalPoint;
if ((0, _shared.getContextEnv)() === 'browser') {
var canvas = this.renderer;
originalPoint = (0, _shared.getRelativePositionFromEvent)({
x: event.clientX,
y: event.clientY
}, canvas.getBoundingClientRect());
} else {
// vm 环境
// global.getRelativePositionFromEvent
}
// 无法根据事件和 renderer 获取合法的点击位置
if (!originalPoint) {
return {};
}
originalPoint = this.revisePointByViewPort(originalPoint);
return this.getHitTargetOriginal(originalPoint, this.container, this.interactiveConfig, type);
}
/**
* 主动传入一个点位做一次 hitTest,返回结果
* @param point 是相对于 canvas 左上角的点击位置
*/
}, {
key: "hitTargetOriginalByPoint",
value: function hitTargetOriginalByPoint(point) {
var originalPoint = this.revisePointByViewPort(point);
return this.getHitTargetOriginal(originalPoint, this.container, this.interactiveConfig, 'isClickable');
}
}, {
key: "revisePointByViewPort",
value: function revisePointByViewPort(point) {
if (this.viewport) {
var _this$viewport = this.viewport,
x = _this$viewport.x,
y = _this$viewport.y;
return {
x: point.x - x,
y: point.y - y
};
}
return point;
}
}, {
key: "onHoverIn",
value: function onHoverIn(target, event) {
var config = this.interactiveConfig.get(target);
if (config && config.isHoverable && config.onHoverIn) {
this.hoverTarget = target;
config.onHoverIn(_sceneEvent.SceneEvent.create(event, this.getCoordinateCtrl, this.hitTargetOriginalByPoint));
}
}
}, {
key: "onHoverOut",
value: function onHoverOut(target, event) {
var config = this.interactiveConfig.get(target);
if (config && config.isHoverable && config.onHoverOut) {
config.onHoverOut(_sceneEvent.SceneEvent.create(event, this.getCoordinateCtrl, this.hitTargetOriginalByPoint));
}
}
}], [{
key: "create",
value: function create(option) {
return new InteractiveController(option);
}
}]);
}();