UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

116 lines (115 loc) 4.52 kB
"use strict"; import { BaseRayObjectIntersectionsController } from "./_BaseRayObjectIntersectionsController"; import { filterObjectsWithMatchButtonsConfig, propertyMatchesButtonsConfig, buttonsConfigFromEvent } from "./Common"; import { ParamConfig } from "../../../../nodes/utils/params/ParamsConfig"; import { MouseButtons } from "../../../../../core/MouseButton"; import { CursorMoveMonitor } from "../../../../../core/CursorMoveMonitor"; const _buttonsConfig = { buttons: MouseButtons.LEFT, ctrl: false, shift: false, alt: false }; function hasPropertiesWithCursorMoveLessThan(options, distance) { for (const option of options) { if (distance < option.click.maxCursorMoveDistance) { return true; } } return false; } export function ClickParamConfig(Base) { return class Mixin extends Base { constructor() { super(...arguments); /** @param max cursor move distance */ this.maxCursorMoveDistance = ParamConfig.FLOAT(0.05, { range: [0, 1], rangeLocked: [true, false] }); /** @param max duration */ this.maxDuration = ParamConfig.INTEGER(200, { range: [0, 1e3], rangeLocked: [true, false] }); } }; } export class RayObjectIntersectionsMouseClickController extends BaseRayObjectIntersectionsController { constructor() { super(...arguments); this._propertiesListByObject = /* @__PURE__ */ new Map(); this._intersectedStateOnMousedownByObject = /* @__PURE__ */ new Map(); this._intersectedStateOnMouseupByObject = /* @__PURE__ */ new Map(); this._objectsMatchingEventConfig = []; this._objectsIntersectedOnMousedown = []; this._cursorMoveMonitor = new CursorMoveMonitor(); this._mousedownReceivedAt = 0; this._bound = { mouseup: this._onMouseup.bind(this) }; } onMousedown(event) { this._mousedownEvent = event; this._mousedownReceivedAt = performance.now(); if (this._objects.length == 0) { return; } filterObjectsWithMatchButtonsConfig( event, this._objects, this._propertiesListByObject, this._objectsMatchingEventConfig ); if (this._objectsMatchingEventConfig.length == 0) { return; } document.addEventListener("mouseup", this._bound.mouseup); document.addEventListener("touchend", this._bound.mouseup); this._cursorMoveMonitor.addPointermoveEventListener( this._scene.eventsDispatcher.pointerEventsController.cursor() ); this._setIntersectedState(this._objectsMatchingEventConfig, this._intersectedStateOnMousedownByObject); } _onMouseup() { document.removeEventListener("mouseup", this._bound.mouseup); document.removeEventListener("touchend", this._bound.mouseup); this._cursorMoveMonitor.removeEventListener(); const event = this._mousedownEvent; if (!event) { return; } this._mousedownEvent = void 0; const duration = performance.now() - this._mousedownReceivedAt; const movedCursorDistance = this._cursorMoveMonitor.movedCursorDistance(); const objects = this._objectsMatchingEventConfig; this._objectsIntersectedOnMousedown.length = 0; for (const object of objects) { const propertiesList = this._propertiesListByObject.get(object); if (propertiesList && hasPropertiesWithCursorMoveLessThan(propertiesList, movedCursorDistance)) { const isIntersectingOnMousedown = this._intersectedStateOnMousedownByObject.get(object); if (isIntersectingOnMousedown) { this._objectsIntersectedOnMousedown.push(object); } } } if (this._objectsIntersectedOnMousedown.length == 0) { return; } this._setIntersectedState(objects, this._intersectedStateOnMouseupByObject); buttonsConfigFromEvent(event, _buttonsConfig); const objectsIntersectedOnMousedown = this._objectsIntersectedOnMousedown; for (const object of objectsIntersectedOnMousedown) { const propertiesList = this._propertiesListByObject.get(object); if (propertiesList) { const isIntersectingOnMouseup = this._intersectedStateOnMouseupByObject.get(object); if (isIntersectingOnMouseup == true) { for (const properties of propertiesList) { if (movedCursorDistance < properties.click.maxCursorMoveDistance && duration < properties.click.maxDuration && propertyMatchesButtonsConfig(properties.config, _buttonsConfig)) { properties.click.callback(); } } } } } } }