mirror of
https://github.com/Terncode/pixel.horse.git
synced 2026-09-26 06:35:51 +02:00
Archive commit
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
import { Key, InputController } from './input';
|
||||
import { Point } from '../../common/interfaces';
|
||||
import { setTransform } from '../../common/utils';
|
||||
import { InputManager } from './inputManager';
|
||||
|
||||
function getTouch(e: TouchEvent, id: number) {
|
||||
if (id !== -1) {
|
||||
for (let i = 0; i < e.changedTouches.length; ++i) {
|
||||
const touch = e.changedTouches.item(i);
|
||||
|
||||
if (touch && touch.identifier === id) {
|
||||
return touch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const TOUCH_DEADZONE = 15;
|
||||
const TOUCH_MAX = 100;
|
||||
|
||||
export class TouchController implements InputController {
|
||||
private initialized = false;
|
||||
private touchId = -1;
|
||||
private touch2Id = -1;
|
||||
private touchStart: Point = { x: 0, y: 0 };
|
||||
private touchCurrent: Point = { x: 0, y: 0 };
|
||||
private touchIsDrag = false;
|
||||
private tapInvalidated = false;
|
||||
private origin?: HTMLElement;
|
||||
private position?: HTMLElement;
|
||||
private originShown = false;
|
||||
private originTransform?: string;
|
||||
private positionShown = false;
|
||||
private positionTransform?: string;
|
||||
private element?: HTMLElement;
|
||||
constructor(private manager: InputManager) {
|
||||
}
|
||||
initialize(element: HTMLElement) {
|
||||
if (!this.initialized) {
|
||||
this.initialized = true;
|
||||
this.element = element;
|
||||
this.origin = document.getElementById('touch-origin')!;
|
||||
this.position = document.getElementById('touch-position')!;
|
||||
|
||||
element.addEventListener('touchstart', this.touchstart);
|
||||
element.addEventListener('touchmove', this.touchmove);
|
||||
element.addEventListener('touchend', this.touchend);
|
||||
window.addEventListener('touchend', this.blur);
|
||||
window.addEventListener('blur', this.blur);
|
||||
}
|
||||
}
|
||||
release() {
|
||||
this.initialized = false;
|
||||
|
||||
if (this.element) {
|
||||
this.element.removeEventListener('touchstart', this.touchstart);
|
||||
this.element.removeEventListener('touchmove', this.touchmove);
|
||||
this.element.removeEventListener('touchend', this.touchend);
|
||||
this.element = undefined;
|
||||
}
|
||||
|
||||
window.removeEventListener('touchend', this.blur);
|
||||
window.removeEventListener('blur', this.blur);
|
||||
}
|
||||
update() {
|
||||
const showOrigin = this.touchIsDrag && this.touchId !== -1;
|
||||
const showPosition = this.touchId !== -1;
|
||||
|
||||
if (this.origin && this.position) {
|
||||
if (this.originShown !== showOrigin) {
|
||||
this.originShown = showOrigin;
|
||||
this.origin.style.display = showOrigin ? 'block' : 'none';
|
||||
}
|
||||
|
||||
if (this.positionShown !== showPosition) {
|
||||
this.positionShown = showPosition;
|
||||
this.position.style.display = showPosition ? 'block' : 'none';
|
||||
}
|
||||
|
||||
if (showOrigin) {
|
||||
const transform = `translate3d(${this.touchStart.x - 50}px, ${this.touchStart.y - 50}px, 0px)`;
|
||||
|
||||
if (this.originTransform !== transform) {
|
||||
this.originTransform = transform;
|
||||
setTransform(this.origin, transform);
|
||||
}
|
||||
}
|
||||
|
||||
if (showPosition) {
|
||||
const transform = `translate3d(${this.touchCurrent.x - 25}px, ${this.touchCurrent.y - 25}px, 0px)`;
|
||||
|
||||
if (this.positionTransform !== transform) {
|
||||
this.positionTransform = transform;
|
||||
setTransform(this.position, transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
clear() {
|
||||
}
|
||||
private reset() {
|
||||
this.touch2Id = -1;
|
||||
this.resetTouch();
|
||||
}
|
||||
private resetTouch() {
|
||||
this.touchId = -1;
|
||||
this.touchStart = this.touchCurrent = { x: 0, y: 0 };
|
||||
this.touchIsDrag = false;
|
||||
this.manager.setValue(Key.TOUCH, 0);
|
||||
this.updateInput();
|
||||
}
|
||||
private updateInput() {
|
||||
const dy = this.touchStart.y - this.touchCurrent.y;
|
||||
const dx = this.touchStart.x - this.touchCurrent.x;
|
||||
const theta = Math.atan2(dy, dx);
|
||||
const dist = Math.sqrt(dy * dy + dx * dx);
|
||||
|
||||
if (dist > TOUCH_DEADZONE) {
|
||||
const scaledDist = Math.min((dist - TOUCH_DEADZONE) / (TOUCH_MAX - TOUCH_DEADZONE), 1);
|
||||
this.touchIsDrag = true;
|
||||
this.manager.setValue(Key.GAMEPAD_AXIS1_X, -Math.cos(theta) * scaledDist);
|
||||
this.manager.setValue(Key.GAMEPAD_AXIS1_Y, -Math.sin(theta) * scaledDist);
|
||||
} else {
|
||||
this.manager.setValue(Key.GAMEPAD_AXIS1_X, 0);
|
||||
this.manager.setValue(Key.GAMEPAD_AXIS1_Y, 0);
|
||||
}
|
||||
}
|
||||
private touchstart = (e: any) => {
|
||||
e.cancellable && e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
this.manager.usingTouch = true;
|
||||
|
||||
if (this.touchId === -1) {
|
||||
const touch = e.changedTouches.item(0);
|
||||
|
||||
if (touch) {
|
||||
this.tapInvalidated = false;
|
||||
this.touchId = touch.identifier;
|
||||
this.touchStart = this.touchCurrent = this.getTouchXY(touch);
|
||||
this.manager.setValue(Key.MOUSE_X, this.touchStart.x);
|
||||
this.manager.setValue(Key.MOUSE_Y, this.touchStart.y);
|
||||
this.manager.setValue(Key.TOUCH, 1);
|
||||
}
|
||||
} else if (this.touch2Id === -1) {
|
||||
const touch = e.changedTouches.item(0);
|
||||
|
||||
if (touch) {
|
||||
this.tapInvalidated = true;
|
||||
this.touch2Id = touch.identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
private touchmove = (e: any) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const touch = getTouch(e, this.touchId);
|
||||
|
||||
if (touch) {
|
||||
this.touchCurrent = this.getTouchXY(touch);
|
||||
this.manager.setValue(Key.MOUSE_X, this.touchCurrent.x);
|
||||
this.manager.setValue(Key.MOUSE_Y, this.touchCurrent.y);
|
||||
this.updateInput();
|
||||
}
|
||||
}
|
||||
private touchend = (e: any) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const touch = getTouch(e, this.touchId);
|
||||
|
||||
if (touch) {
|
||||
if (!this.touchIsDrag && !this.tapInvalidated) {
|
||||
this.manager.setValue(Key.MOUSE_X, this.touchStart.x);
|
||||
this.manager.setValue(Key.MOUSE_Y, this.touchStart.y);
|
||||
this.manager.setValue(Key.TOUCH_CLICK, 1);
|
||||
}
|
||||
|
||||
this.resetTouch();
|
||||
}
|
||||
|
||||
const touch2 = getTouch(e, this.touch2Id);
|
||||
|
||||
if (touch2) {
|
||||
this.manager.setValue(Key.TOUCH_SECOND_CLICK, 1);
|
||||
this.touch2Id = -1;
|
||||
}
|
||||
}
|
||||
private blur = () => {
|
||||
this.reset();
|
||||
}
|
||||
private getTouchXY(touch: Touch) {
|
||||
const { left, top } = this.element!.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
x: touch.clientX - left,
|
||||
y: touch.clientY - top,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user