UNPKG

@polygonjs/polygonjs

Version:

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

136 lines (135 loc) 5.13 kB
"use strict"; import { Vector2 } from "three"; import { radToDeg } from "../../../../../core/math/_Module"; import { BaseRayObjectIntersectionsController } from "./_BaseRayObjectIntersectionsController"; import { filterObjectsWithMatchButtonConfig, buttonConfigFromEvent, propertyMatchesButtonConfig } from "./Common"; import { ParamConfig } from "../../../../nodes/utils/params/ParamsConfig"; import { MouseButton } from "../../../../../core/MouseButton"; const _tmp = new Vector2(); const _buttonConfig = { button: MouseButton.LEFT, ctrl: false, shift: false, alt: false }; function degAngle(radians) { if (radians > Math.PI) { radians -= Math.PI * 2; } return radToDeg(radians); } export const ANGLE_DEGREES = { LEFT: degAngle(_tmp.set(-1, 0).angle()), RIGHT: degAngle(_tmp.set(1, 0).angle()), UP: degAngle(_tmp.set(0, 1).angle()), DOWN: degAngle(_tmp.set(0, -1).angle()) }; const DEFAULT_MIN_CURSOR_MOVE_DISTANCE = 0.05; export function SwipeParamConfig(Base) { return class Mixin extends Base { constructor() { super(...arguments); /** @param angle */ this.angle = ParamConfig.FLOAT(0, { range: [-180, 180], rangeLocked: [true, false] }); /** @param angle margin */ this.angleMargin = ParamConfig.FLOAT(45, { range: [0, 180], rangeLocked: [true, false] }); /** @param min distance */ this.minDistance = ParamConfig.FLOAT(DEFAULT_MIN_CURSOR_MOVE_DISTANCE, { range: [0, 1], rangeLocked: [true, false] }); } }; } function optionsContainsAngle(options, angle) { return angle >= options.angle - options.angleMargin && angle <= options.angle + options.angleMargin; } const _cursorDelta = new Vector2(); export class RayObjectIntersectionsSwipeController 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._cursorOnPointerdown = new Vector2(); this._cursorOnPointerup = new Vector2(); this._bound = { pointerup: this._onPointerup.bind(this) }; } onPointerdown(event) { this._pointerdownEvent = event; 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._setIntersectedState(this._objectsMatchingEventConfig, this._intersectedStateOnPointerdownByObject); this._getCursor(this._cursorOnPointerdown); } _onPointerup(_event) { document.removeEventListener("pointerup", this._bound.pointerup); document.removeEventListener("touchend", this._bound.pointerup); const event = this._pointerdownEvent; if (!event) { return; } this._pointerdownEvent = void 0; const objects = this._objects; this._objectsIntersectedOnPointerdown.length = 0; for (const object of objects) { const propertiesList = this._propertiesListByObject.get(object); if (propertiesList) { const isIntersectingOnPointerdown = this._intersectedStateOnPointerdownByObject.get(object); if (isIntersectingOnPointerdown) { this._objectsIntersectedOnPointerdown.push(object); } } } if (this._objectsIntersectedOnPointerdown.length == 0) { return; } this._getCursor(this._cursorOnPointerup); _cursorDelta.copy(this._cursorOnPointerup).sub(this._cursorOnPointerdown); let radians = _cursorDelta.angle(); const degrees = degAngle(radians); const distance = _cursorDelta.manhattanLength(); 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 (distance > properties.swipe.minDistance && optionsContainsAngle(properties.swipe, degrees) && propertyMatchesButtonConfig(properties.config, _buttonConfig)) { properties.swipe.callback(); } } } } } } _getCursor(target) { const pointerEventsController = this._scene.eventsDispatcher.pointerEventsController; const cursor = pointerEventsController.cursor().value; target.copy(cursor); } }