From 46545d54cddd46f9792b2461c9094dd2e2029eb3 Mon Sep 17 00:00:00 2001 From: Peter Date: Fri, 13 Sep 2024 01:16:33 +0200 Subject: [PATCH] refactor: events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * (fix) BREAKING - remove `event.intersects` – use `event.intersections` * (fix) BREAKING - remove `event.stopPropagating` – use `event.stopPropagation` * (fix) BREAKING – from TresCanvas, don't emit pointer/click events bubbled from Tres objects * (fix) BREAKING – `event.delta` is now reset to `0` following a `click`. * (fix) BREAKING – `pointerleave` handlers were sent previous intersections at `event.intersections`, now current intersections. * (fix) BREAKING – `@dblclick` now fires whenever the canvas `dblclick` is emitted. Any TresObject with an `@dblclick` handler will receive the event if it is under the pointer. (Previously objects not under the initial click did not receive the `@dblclick`.) * (fix) `event.pointer` is now defined – previously typed but was `undefined` in implementation. * (fix) `event.unprojectedPoint` is now properly calculated. Was previously left as `TODO`. * (fix) `event.eventObject` holds the object that registered the event handler. Was previously typed but `undefined` in implementation. * (fix) use Vue-style ("flatcase") event names, e.g. `@pointerdown`. Keep support for old-style ("kebab-case") event names, e.g. `@pointer-down`, and warn. Mixing both on the same object is not supported and may lead to handlers being overwritten. * (fix) `@pointer{leave,out}` was fired multiple times on a single "leave" – Issue #801 * (feat) BREAKING – `pointermissed` fires when the object that registered the handler is missed – previously only fired when ALL objects were missed * (feat) add filtering/sorting for intersections, prior to handling events. `:events={filter: (intersections) => ...}` * (feat) support Vue event modifiers – `stop, prevent, self, once`. (Tres cannot support `passive` and does not currently support `capture`.) * (feat) via `:events-target` prop, allow users to specify an HTML `addEventListener` target – allows Tres to respond to events, even if there's an overlay on the canvas. * (feat) via `:events-enabled` prop, allow `eventManager` to be enabled/disabled while Tres is running. * (feat) via `:events` prop, allow `eventManager` functions to be set/overwritten (non-reactive). * (feat) via `:events` prop, allow events system to be disabled completely: `` (non-reactive) * (feat) `pointer{leave,out}` is triggered (if necessary) just prior to object removal. * (feat) `:blocking="true"` makes a subtree "solid"; objects behind objects in the subtree will not be "hit". --- playground/vue/src/pages/events/Blocking.vue | 111 ++ playground/vue/src/pages/events/Connect.vue | 163 +++ .../src/pages/events/DeprecatedEventNames.vue | 87 ++ .../vue/src/pages/events/DynamicObjects.vue | 12 +- playground/vue/src/pages/events/Filter.vue | 141 +++ playground/vue/src/pages/events/NoEvents.vue | 78 ++ .../src/pages/events/PointerEnterLeave.vue | 77 ++ .../src/pages/events/RemoveInteractivity.vue | 102 ++ .../vue/src/pages/events/StopPropagation.vue | 153 +++ .../vue/src/pages/events/TargetEnabled.vue | 137 +++ playground/vue/src/pages/events/index.vue | 27 +- .../vue/src/pages/events/propagation/Box.vue | 44 - .../src/pages/events/propagation/index.vue | 188 --- .../711/index.vue} | 7 + playground/vue/src/router/routes/events.ts | 46 +- playground/vue/src/router/routes/issues.ts | 5 + pnpm-lock.yaml | 172 ++- src/components/TresCanvas.vue | 27 +- src/composables/index.ts | 2 - src/composables/useRaycaster/index.ts | 212 ---- .../useTresContextProvider/index.ts | 20 +- src/composables/useTresEventManager/index.ts | 231 ---- src/core/nodeOps.ts | 52 +- src/types/index.ts | 54 +- src/utils/createEventManager/README.md | 39 + src/utils/createEventManager/const.ts | 83 ++ .../createEventManager.test.ts | 365 ++++++ .../createEventManager/createEventManager.ts | 146 +++ .../deprecatedEvents.test.ts | 51 + .../createEventManager/deprecatedEvents.ts | 89 ++ .../createEventManager/eventModifiers.test.ts | 317 +++++ .../createEventManager/eventModifiers.ts | 255 ++++ src/utils/createEventManager/eventsNoop.ts | 40 + .../createEventManager/eventsRaycast.test.ts | 1066 +++++++++++++++++ src/utils/createEventManager/eventsRaycast.ts | 430 +++++++ src/utils/createEventManager/index.ts | 6 + .../useEventsOptions.test.ts | 367 ++++++ .../createEventManager/useEventsOptions.ts | 78 ++ src/utils/index.ts | 2 +- 39 files changed, 4594 insertions(+), 888 deletions(-) create mode 100644 playground/vue/src/pages/events/Blocking.vue create mode 100644 playground/vue/src/pages/events/Connect.vue create mode 100644 playground/vue/src/pages/events/DeprecatedEventNames.vue create mode 100644 playground/vue/src/pages/events/Filter.vue create mode 100644 playground/vue/src/pages/events/NoEvents.vue create mode 100644 playground/vue/src/pages/events/PointerEnterLeave.vue create mode 100644 playground/vue/src/pages/events/RemoveInteractivity.vue create mode 100644 playground/vue/src/pages/events/StopPropagation.vue create mode 100644 playground/vue/src/pages/events/TargetEnabled.vue delete mode 100644 playground/vue/src/pages/events/propagation/Box.vue delete mode 100644 playground/vue/src/pages/events/propagation/index.vue rename playground/vue/src/pages/{events/FpsDropsReproduction.vue => issues/711/index.vue} (77%) delete mode 100644 src/composables/useRaycaster/index.ts delete mode 100644 src/composables/useTresEventManager/index.ts create mode 100644 src/utils/createEventManager/README.md create mode 100644 src/utils/createEventManager/const.ts create mode 100644 src/utils/createEventManager/createEventManager.test.ts create mode 100644 src/utils/createEventManager/createEventManager.ts create mode 100644 src/utils/createEventManager/deprecatedEvents.test.ts create mode 100644 src/utils/createEventManager/deprecatedEvents.ts create mode 100644 src/utils/createEventManager/eventModifiers.test.ts create mode 100644 src/utils/createEventManager/eventModifiers.ts create mode 100644 src/utils/createEventManager/eventsNoop.ts create mode 100644 src/utils/createEventManager/eventsRaycast.test.ts create mode 100644 src/utils/createEventManager/eventsRaycast.ts create mode 100644 src/utils/createEventManager/index.ts create mode 100644 src/utils/createEventManager/useEventsOptions.test.ts create mode 100644 src/utils/createEventManager/useEventsOptions.ts diff --git a/playground/vue/src/pages/events/Blocking.vue b/playground/vue/src/pages/events/Blocking.vue new file mode 100644 index 000000000..f72923bdb --- /dev/null +++ b/playground/vue/src/pages/events/Blocking.vue @@ -0,0 +1,111 @@ + + + + diff --git a/playground/vue/src/pages/events/Connect.vue b/playground/vue/src/pages/events/Connect.vue new file mode 100644 index 000000000..b07c27b4c --- /dev/null +++ b/playground/vue/src/pages/events/Connect.vue @@ -0,0 +1,163 @@ + + + + diff --git a/playground/vue/src/pages/events/DeprecatedEventNames.vue b/playground/vue/src/pages/events/DeprecatedEventNames.vue new file mode 100644 index 000000000..b5b97e230 --- /dev/null +++ b/playground/vue/src/pages/events/DeprecatedEventNames.vue @@ -0,0 +1,87 @@ + + + + diff --git a/playground/vue/src/pages/events/DynamicObjects.vue b/playground/vue/src/pages/events/DynamicObjects.vue index c0b94344c..808a6a51d 100644 --- a/playground/vue/src/pages/events/DynamicObjects.vue +++ b/playground/vue/src/pages/events/DynamicObjects.vue @@ -1,6 +1,6 @@ @@ -43,7 +43,7 @@ const shrink = (event) => { - + { :args="[0.5, 16, 16]" :position="hotspot.position" @click="console.log('click', index)" - @pointer-enter="grow" - @pointer-leave="shrink" + @pointerenter="grow" + @pointerleave="shrink" > diff --git a/playground/vue/src/pages/events/Filter.vue b/playground/vue/src/pages/events/Filter.vue new file mode 100644 index 000000000..ae4c8eed8 --- /dev/null +++ b/playground/vue/src/pages/events/Filter.vue @@ -0,0 +1,141 @@ + + + + + + diff --git a/playground/vue/src/pages/events/NoEvents.vue b/playground/vue/src/pages/events/NoEvents.vue new file mode 100644 index 000000000..1b4d5a0ae --- /dev/null +++ b/playground/vue/src/pages/events/NoEvents.vue @@ -0,0 +1,78 @@ + + + + diff --git a/playground/vue/src/pages/events/PointerEnterLeave.vue b/playground/vue/src/pages/events/PointerEnterLeave.vue new file mode 100644 index 000000000..a9ef4e3fc --- /dev/null +++ b/playground/vue/src/pages/events/PointerEnterLeave.vue @@ -0,0 +1,77 @@ + + + + diff --git a/playground/vue/src/pages/events/RemoveInteractivity.vue b/playground/vue/src/pages/events/RemoveInteractivity.vue new file mode 100644 index 000000000..4e8f3a7ca --- /dev/null +++ b/playground/vue/src/pages/events/RemoveInteractivity.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/playground/vue/src/pages/events/StopPropagation.vue b/playground/vue/src/pages/events/StopPropagation.vue new file mode 100644 index 000000000..8b1bfcfa1 --- /dev/null +++ b/playground/vue/src/pages/events/StopPropagation.vue @@ -0,0 +1,153 @@ + + + + diff --git a/playground/vue/src/pages/events/TargetEnabled.vue b/playground/vue/src/pages/events/TargetEnabled.vue new file mode 100644 index 000000000..25b0f2d0d --- /dev/null +++ b/playground/vue/src/pages/events/TargetEnabled.vue @@ -0,0 +1,137 @@ + + + + + diff --git a/playground/vue/src/pages/events/index.vue b/playground/vue/src/pages/events/index.vue index 41e098405..887bffe6e 100644 --- a/playground/vue/src/pages/events/index.vue +++ b/playground/vue/src/pages/events/index.vue @@ -21,25 +21,23 @@ const { stopPropagation } = useControls({ }) function onClick(ev: ThreeEvent) { - console.log('click', ev) if (stopPropagation.value) { ev.stopPropagation() } - ev.object.material.color.set('#008080') + ev.eventObject.material?.color.set('#008080') } function onDoubleClick(ev: ThreeEvent) { - console.log('double-click', ev) if (stopPropagation.value) { ev.stopPropagation() } - ev.object.material.color.set('#FFD700') + ev.eventObject.material.color.set('#FFD700') } function onPointerEnter(ev: ThreeEvent) { if (stopPropagation.value) { ev.stopPropagation() } - ev.object.material.color.set('#CCFF03') + ev.eventObject.material.color.set('#CCFF03') } function onPointerLeave(ev: ThreeEvent) { if (stopPropagation.value) { ev.stopPropagation() } - /* ev.object.material.color.set('#efefef') */ + ev.eventObject.material.color.set('#efefef') } function onPointerMove(ev: ThreeEvent) { @@ -47,14 +45,13 @@ function onPointerMove(ev: ThreeEvent) { } function onContextMenu(ev: ThreeEvent) { - console.log('context-menu', ev) if (stopPropagation.value) { ev.stopPropagation() } - ev.object.material.color.set('#FF4500') + ev.eventObject.material.color.set('#FF4500') } function onPointerMissed(ev: ThreeEvent) { - console.log('pointer-missed', ev) if (stopPropagation.value) { ev.stopPropagation() } + ev.eventObject.material.color.set('#000000') } @@ -79,12 +76,12 @@ function onPointerMissed(ev: ThreeEvent) { :key="`${[x, y, z]}`" :position="[x, y, z]" @click="onClick" - @double-click="onDoubleClick" - @pointer-enter="onPointerEnter" - @pointer-leave="onPointerLeave" - @pointer-move="onPointerMove" - @context-menu="onContextMenu" - @pointer-missed="onPointerMissed" + @dblclick="onDoubleClick" + @pointerenter="onPointerEnter" + @pointerleave="onPointerLeave" + @pointermove="onPointerMove" + @contextmenu="onContextMenu" + @pointermissed="onPointerMissed" > diff --git a/playground/vue/src/pages/events/propagation/Box.vue b/playground/vue/src/pages/events/propagation/Box.vue deleted file mode 100644 index 3409cdae0..000000000 --- a/playground/vue/src/pages/events/propagation/Box.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - diff --git a/playground/vue/src/pages/events/propagation/index.vue b/playground/vue/src/pages/events/propagation/index.vue deleted file mode 100644 index f2c921c33..000000000 --- a/playground/vue/src/pages/events/propagation/index.vue +++ /dev/null @@ -1,188 +0,0 @@ - - - diff --git a/playground/vue/src/pages/events/FpsDropsReproduction.vue b/playground/vue/src/pages/issues/711/index.vue similarity index 77% rename from playground/vue/src/pages/events/FpsDropsReproduction.vue rename to playground/vue/src/pages/issues/711/index.vue index 03a5fd35a..b3984a60a 100644 --- a/playground/vue/src/pages/events/FpsDropsReproduction.vue +++ b/playground/vue/src/pages/issues/711/index.vue @@ -22,6 +22,13 @@ const gl = {