UNPKG

@polygonjs/polygonjs

Version:

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

116 lines (115 loc) 4.57 kB
"use strict"; import { BaseRayObjectIntersectionsController } from "./_BaseRayObjectIntersectionsController"; import { filterObjectsWithMatchButtonConfig, propertyMatchesButtonConfig, buttonConfigFromEvent } from "./Common"; import { ParamConfig } from "../../../../nodes/utils/params/ParamsConfig"; import { MouseButton } from "../../../../../core/MouseButton"; import { CursorMoveMonitor } from "../../../../../core/CursorMoveMonitor"; const _buttonConfig = { button: MouseButton.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 RayObjectIntersectionsClickController extends BaseRayObjectIntersectionsController { constructor() { super(...arguments); this._propertiesListByObject = /* @__PURE__ */ new Map(); this._intersectedStateOnPointerdownByObject = /* @__PURE__ */ new Map(); this._intersectedStateOnPointerupByObject = /* @__PURE__ */ new Map(); this._objectsMatchingEventConfig = []; this._objectsIntersectedOnPointerdown = []; this._cursorMoveMonitor = new CursorMoveMonitor(); this._pointerdownReceivedAt = 0; this._bound = { pointerup: this._onPointerup.bind(this) }; } onPointerdown(event) { this._pointerdownEvent = event; this._pointerdownReceivedAt = performance.now(); if (this._objects.length == 0) { return; } filterObjectsWithMatchButtonConfig( event, this._objects, this._propertiesListByObject, this._objectsMatchingEventConfig ); if (this._objectsMatchingEventConfig.length == 0) { return; } document.addEventListener("pointerup", this._bound.pointerup); document.addEventListener("touchend", this._bound.pointerup); this._cursorMoveMonitor.addPointermoveEventListener( this._scene.eventsDispatcher.pointerEventsController.cursor() ); this._setIntersectedState(this._objectsMatchingEventConfig, this._intersectedStateOnPointerdownByObject); } _onPointerup() { document.removeEventListener("pointerup", this._bound.pointerup); document.removeEventListener("touchend", this._bound.pointerup); this._cursorMoveMonitor.removeEventListener(); const event = this._pointerdownEvent; if (!event) { return; } this._pointerdownEvent = void 0; const duration = performance.now() - this._pointerdownReceivedAt; const movedCursorDistance = this._cursorMoveMonitor.movedCursorDistance(); const objects = this._objectsMatchingEventConfig; this._objectsIntersectedOnPointerdown.length = 0; for (const object of objects) { const propertiesList = this._propertiesListByObject.get(object); if (propertiesList && hasPropertiesWithCursorMoveLessThan(propertiesList, movedCursorDistance)) { const isIntersectingOnPointerdown = this._intersectedStateOnPointerdownByObject.get(object); if (isIntersectingOnPointerdown) { this._objectsIntersectedOnPointerdown.push(object); } } } if (this._objectsIntersectedOnPointerdown.length == 0) { return; } this._setIntersectedState(objects, this._intersectedStateOnPointerupByObject); buttonConfigFromEvent(event, _buttonConfig); const objectsIntersectedOnPointerdown = this._objectsIntersectedOnPointerdown; for (const object of objectsIntersectedOnPointerdown) { const propertiesList = this._propertiesListByObject.get(object); if (propertiesList) { const isIntersectingOnPointerup = this._intersectedStateOnPointerupByObject.get(object); if (isIntersectingOnPointerup == true) { for (const properties of propertiesList) { if (movedCursorDistance < properties.click.maxCursorMoveDistance && duration < properties.click.maxDuration && propertyMatchesButtonConfig(properties.config, _buttonConfig)) { properties.click.callback(); } } } } } } }