UNPKG

@turbox3d/event-manager

Version:

Large-scale productivity application event management library

391 lines (390 loc) 19 kB
"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); } }]); }();