Skip to content

Commit

Permalink
feat(input): add single touch handling
Browse files Browse the repository at this point in the history
  • Loading branch information
tomaisthorpe committed Jun 15, 2024
1 parent 89096a8 commit f8aeeb5
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/lucky-jars-yell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tedengine/ted": minor
---

Add basic touch handling
1 change: 1 addition & 0 deletions packages/ted/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export * from './input/events';
export { default as TKeyboard } from './input/keyboard';
export { default as TMouse } from './input/mouse';
export * from './input/mouse';
export { default as TTouch } from './input/touch';
export { default as TSimpleController } from './input/simple-controller';

export { default as TTransform } from './math/transform';
Expand Down
20 changes: 20 additions & 0 deletions packages/ted/src/input/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ export enum TEventTypesInput {
MouseUp = 'mouseup',
MouseDown = 'mousedown',
MouseMove = 'mousemove',
TouchStart = 'touchstart',
TouchEnd = 'touchend',
TouchMove = 'touchmove',
TouchCancel = 'touchcancel',
ActionPressed = 'controller_actionpressed',
ActionReleased = 'controller_actionreleased',
}
Expand Down Expand Up @@ -40,6 +44,22 @@ export interface TMouseMoveEvent extends TMouseLocation {
type: TEventTypesInput.MouseMove;
}

export interface TTouchStartEvent extends TMouseLocation {
type: TEventTypesInput.TouchStart;
}

export interface TTouchEndEvent extends TMouseLocation {
type: TEventTypesInput.TouchEnd;
}

export interface TTouchMoveEvent extends TMouseLocation {
type: TEventTypesInput.TouchMove;
}

export interface TTouchCancelEvent extends TMouseLocation {
type: TEventTypesInput.TouchCancel;
}

export interface TActionPressedEvent {
type: TEventTypesInput.ActionPressed;
subType: string; // Action pressed
Expand Down
100 changes: 100 additions & 0 deletions packages/ted/src/input/touch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { vec2 } from 'gl-matrix';
import type TEventQueue from '../core/event-queue';
import type {
TMouseLocation,
TTouchCancelEvent,
TTouchEndEvent,
TTouchMoveEvent,
TTouchStartEvent,
} from './events';
import { TEventTypesInput } from './events';

export default class TMouse {
private touchMoveListener: (e: TouchEvent) => void;
private touchStartListener: (e: TouchEvent) => void;
private touchEndListener: (e: TouchEvent) => void;
private touchCancelListener: (e: TouchEvent) => void;

constructor(
eventQueue: TEventQueue,
private canvas: HTMLCanvasElement,
) {
this.touchMoveListener = (e) => this.handleTouchMove(e, eventQueue);
this.touchMoveListener = this.touchMoveListener.bind(this);
window.addEventListener('touchmove', this.touchMoveListener);

this.touchStartListener = (e) => this.handleTouchStart(e, eventQueue);
this.touchStartListener = this.touchStartListener.bind(this);
this.canvas.addEventListener('touchstart', this.touchStartListener);

this.touchEndListener = (e) => this.handleTouchEnd(e, eventQueue);
this.touchEndListener = this.touchEndListener.bind(this);
this.canvas.addEventListener('touchend', this.touchEndListener);

this.touchCancelListener = (e) => this.handleTouchCancel(e, eventQueue);
this.touchCancelListener = this.touchCancelListener.bind(this);
window.addEventListener('touchcancel', this.touchCancelListener);
}

public destroy() {
window.removeEventListener('touchmove', this.touchMoveListener);
window.removeEventListener('touchcancel', this.touchCancelListener);
this.canvas.removeEventListener('touchstart', this.touchStartListener);
this.canvas.removeEventListener('touchend', this.touchEndListener);
}

private handleTouchMove(e: TouchEvent, eventQueue: TEventQueue) {
const event: TTouchMoveEvent = {
type: TEventTypesInput.TouchMove,
...this.getTouchLocation(e),
};

eventQueue.broadcast(event);
}

private handleTouchStart(e: TouchEvent, eventQueue: TEventQueue) {
const event: TTouchStartEvent = {
type: TEventTypesInput.TouchStart,
...this.getTouchLocation(e),
};

eventQueue.broadcast(event);
}

private handleTouchEnd(e: TouchEvent, eventQueue: TEventQueue) {
const event: TTouchEndEvent = {
type: TEventTypesInput.TouchEnd,
...this.getTouchLocation(e),
};

eventQueue.broadcast(event);
}

private handleTouchCancel(e: TouchEvent, eventQueue: TEventQueue) {
const event: TTouchCancelEvent = {
type: TEventTypesInput.TouchCancel,
...this.getTouchLocation(e),
};

eventQueue.broadcast(event);
}

private getTouchLocation(e: TouchEvent) {
const offset = this.canvas.getBoundingClientRect();

const touch = e.touches[0];
const result: TMouseLocation = {
client: vec2.fromValues(touch.clientX, touch.clientY),
screen: vec2.fromValues(
touch.clientX - offset.left,
touch.clientY - offset.top,
),
clip: vec2.fromValues(
((touch.clientX - offset.left) / this.canvas.clientWidth) * 2 - 1,
((touch.clientY - offset.top) / this.canvas.clientHeight) * -2 + 1,
),
};

return result;
}
}

0 comments on commit f8aeeb5

Please sign in to comment.