diff --git a/CHANGELOG.md b/CHANGELOG.md index 57360757..f640b669 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.6.2] - 2021-01-23 +### Changed + +- Improve event handling + ### Fixed - Hit detection for spritesheet textures diff --git a/src/interfaces/IHitDetection.ts b/src/interfaces/IHitDetection.ts index 98dfeafa..e2700ae0 100644 --- a/src/interfaces/IHitDetection.ts +++ b/src/interfaces/IHitDetection.ts @@ -11,6 +11,7 @@ export type HitEventType = "click" | "pointerdown" | "pointerup"; export interface HitEvent { mouseEvent: MouseEvent; tag?: string; + target: HitDetectionElement; stopPropagation(): void; resumePropagation(): void; diff --git a/src/objects/furniture/FloorFurniture.tsx b/src/objects/furniture/FloorFurniture.tsx index ab9d6774..b924bfb0 100644 --- a/src/objects/furniture/FloorFurniture.tsx +++ b/src/objects/furniture/FloorFurniture.tsx @@ -197,7 +197,7 @@ export class FloorFurniture } public get onPointerUp() { - return this._onPointerDown; + return this._onPointerUp; } public set onPointerUp(value) { diff --git a/src/objects/hitdetection/ClickHandler.ts b/src/objects/hitdetection/ClickHandler.ts index 3b9904c4..e2dcd45a 100644 --- a/src/objects/hitdetection/ClickHandler.ts +++ b/src/objects/hitdetection/ClickHandler.ts @@ -11,8 +11,6 @@ export class ClickHandler { timeout: number; }; - private _didReceiveClick = false; - private _map = new Map(); private _onClick: HitEventHandler | undefined; @@ -86,7 +84,7 @@ export class ClickHandler { this._map.set(name, false); setTimeout(() => { this._map.delete(name); - }, 0); + }); } private _canHandleEvent(name: string) { @@ -95,11 +93,14 @@ export class ClickHandler { private _performDoubleClick(event: HitEvent) { if (this._doubleClickInfo == null) return; + if (event.target !== this._doubleClickInfo.initialEvent.target) return; - event.stopPropagation(); this.onDoubleClick && this.onDoubleClick(this._doubleClickInfo.initialEvent); - this._resetDoubleClick(); + + setTimeout(() => { + this._resetDoubleClick(); + }); } private _resetDoubleClick() { @@ -110,8 +111,6 @@ export class ClickHandler { } private _startDoubleClick(event: HitEvent) { - event.stopPropagation(); - this._doubleClickInfo = { initialEvent: event, timeout: window.setTimeout(() => this._resetDoubleClick(), 350), diff --git a/src/objects/hitdetection/HitDetection.ts b/src/objects/hitdetection/HitDetection.ts index e8e41f72..9f3a05a5 100644 --- a/src/objects/hitdetection/HitDetection.ts +++ b/src/objects/hitdetection/HitDetection.ts @@ -69,7 +69,7 @@ export class HitDetection implements IHitDetection { ) { const elements = this._performHitTest(x, y); - const event = new HitEventImplementation(eventType, domEvent, elements); + const event = new HitEventPropagation(eventType, domEvent, elements); event.resumePropagation(); } @@ -90,7 +90,7 @@ export class HitDetection implements IHitDetection { } } -class HitEventImplementation implements HitEvent { +class HitEventPropagation { private _currentIndex = 0; private _stopped = false; private _tag: string | undefined; @@ -129,7 +129,39 @@ class HitEventImplementation implements HitEvent { if (this._stopped) break; const element = this._path[i]; - element.trigger(this._eventType, this); + + element.trigger(this._eventType, new TargetedHitEvent(this, element)); } } } + +class TargetedHitEvent implements HitEvent { + constructor( + private _base: HitEventPropagation, + private _target: HitDetectionElement + ) {} + + public get target() { + return this._target; + } + + public get mouseEvent() { + return this._base.mouseEvent; + } + + public get tag() { + return this._base.tag; + } + + public set tag(value) { + this._base.tag = value; + } + + stopPropagation(): void { + return this._base.stopPropagation(); + } + + resumePropagation(): void { + return this._base.resumePropagation(); + } +} diff --git a/storybook/stories/Issues.stories.ts b/storybook/stories/Issues.stories.ts index 8e2c6c30..a09095f8 100644 --- a/storybook/stories/Issues.stories.ts +++ b/storybook/stories/Issues.stories.ts @@ -204,6 +204,11 @@ export function IssueWithAvatarEventsNotHandled() { action("Avatar Clicked")(event); }; + + avatar.onDoubleClick = (event) => { + event.stopPropagation(); + }; + furniture.onClick = (event) => { event.stopPropagation(); @@ -211,8 +216,7 @@ export function IssueWithAvatarEventsNotHandled() { setTimeout(() => { furniture.animation = undefined; - event.resumePropagation(); - }, 500); + }, 3500); action("Furniture Clicked")(event); };