2022-07-17 15:16:28 +03:00
|
|
|
export type TPattern = {
|
|
|
|
pattern: TPatternUnit[];
|
|
|
|
}
|
|
|
|
|
|
|
|
export type TPatternUnit = {
|
2022-07-14 17:50:28 +03:00
|
|
|
startDelay: number,
|
|
|
|
duration: number,
|
|
|
|
weakMagnitude: number,
|
|
|
|
strongMagnitude: number,
|
|
|
|
}
|
|
|
|
|
2022-07-17 15:16:28 +03:00
|
|
|
export interface IVibrationActuator {
|
2022-07-14 17:50:28 +03:00
|
|
|
type: string;
|
|
|
|
reset(): void;
|
2022-07-17 15:16:28 +03:00
|
|
|
playEffect(mode: string, pattern: TPatternUnit): void;
|
2022-07-14 17:50:28 +03:00
|
|
|
}
|
|
|
|
|
2022-07-17 15:16:28 +03:00
|
|
|
export interface IGamepad {
|
2022-07-14 17:50:28 +03:00
|
|
|
id: string;
|
|
|
|
index: number;
|
|
|
|
timestamp: number;
|
|
|
|
connected: boolean;
|
|
|
|
vibrationActuator: IVibrationActuator;
|
|
|
|
}
|
|
|
|
|
2022-07-17 15:16:28 +03:00
|
|
|
export interface IVibrator {
|
2022-07-14 17:50:28 +03:00
|
|
|
readonly id: number,
|
|
|
|
readonly canVibrate: boolean;
|
|
|
|
isVibrating: boolean;
|
|
|
|
unit: IGamepad;
|
2022-07-17 15:16:28 +03:00
|
|
|
pattern: TPatternUnit[];
|
2022-07-14 17:50:28 +03:00
|
|
|
update(): void;
|
|
|
|
reset(): void;
|
2022-07-17 15:16:28 +03:00
|
|
|
vibrate(pattern: TPatternUnit[]): void;
|
2022-07-14 17:50:28 +03:00
|
|
|
sleep(ms: number): Promise<number>;
|
|
|
|
}
|
|
|
|
|
2022-07-17 15:16:28 +03:00
|
|
|
export class Vibrator implements IVibrator {
|
2022-07-14 17:50:28 +03:00
|
|
|
readonly id: number;
|
|
|
|
readonly canVibrate: boolean;
|
|
|
|
isVibrating: boolean;
|
|
|
|
unit: IGamepad;
|
2022-07-17 15:16:28 +03:00
|
|
|
pattern: TPatternUnit[];
|
2022-07-14 17:50:28 +03:00
|
|
|
|
|
|
|
constructor(unit: IGamepad) {
|
|
|
|
this.unit = unit;
|
|
|
|
this.id = Date.now();
|
|
|
|
this.canVibrate = (this.unit.vibrationActuator) ? true : false;
|
|
|
|
this.isVibrating = false;
|
|
|
|
this.pattern = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
update(): void {
|
|
|
|
const gamepads = navigator.getGamepads();
|
|
|
|
this.unit = <IGamepad><any>gamepads[this.unit.index];
|
|
|
|
}
|
|
|
|
|
|
|
|
reset(): void {
|
|
|
|
this.isVibrating = false;
|
|
|
|
this.unit.vibrationActuator.reset();
|
|
|
|
}
|
|
|
|
|
2022-07-17 15:16:28 +03:00
|
|
|
async vibrate(pattern: TPatternUnit[]) {
|
2022-07-14 17:50:28 +03:00
|
|
|
this.isVibrating = true;
|
|
|
|
this.pattern = pattern;
|
|
|
|
|
|
|
|
while (this.isVibrating === true) {
|
|
|
|
for (let i = 0; i < this.pattern.length; i++) {
|
|
|
|
if (this.isVibrating === true) {
|
|
|
|
this.unit.vibrationActuator.playEffect('dual-rumble', this.pattern[i]);
|
|
|
|
await this.sleep(this.pattern[i].startDelay + this.pattern[i].duration + 100);
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sleep(ms: number): Promise<number> {
|
|
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
|
|
}
|
2022-07-17 15:16:28 +03:00
|
|
|
}
|