add long press event, multi keybind, mobile whois (fixes #42)

This commit is contained in:
Grant 2024-06-04 13:54:12 -06:00
parent 6f7aad5da8
commit c328a830e8
3 changed files with 52 additions and 16 deletions

View File

@ -12,6 +12,7 @@ import {
PanZoom,
} from "@sc07-canvas/lib/src/renderer/PanZoom";
import { toast } from "react-toastify";
import { KeybindManager } from "./keybinds";
interface CanvasEvents {
/**
@ -48,6 +49,7 @@ export class Canvas extends EventEmitter<CanvasEvents> {
this.PanZoom.addListener("hover", this.handleMouseMove.bind(this));
this.PanZoom.addListener("click", this.handleMouseDown.bind(this));
this.PanZoom.addListener("longPress", this.handleLongPress);
Network.waitFor("pixelLastPlaced").then(
([time]) => (this.lastPlace = time)
@ -60,6 +62,7 @@ export class Canvas extends EventEmitter<CanvasEvents> {
this.PanZoom.removeListener("hover", this.handleMouseMove.bind(this));
this.PanZoom.removeListener("click", this.handleMouseDown.bind(this));
this.PanZoom.removeListener("longPress", this.handleLongPress);
Network.off("pixel", this.handlePixel);
}
@ -120,6 +123,18 @@ export class Canvas extends EventEmitter<CanvasEvents> {
return pixels;
}
handleLongPress = (clientX: number, clientY: number) => {
KeybindManager.handleInteraction(
{
key: "LONG_PRESS",
},
{
clientX,
clientY,
}
);
};
handleMouseDown(e: ClickEvent) {
if (!e.alt && !e.ctrl && !e.meta && !e.shift && e.button === "LCLICK") {
const [x, y] = this.screenToPos(e.clientX, e.clientY);

View File

@ -2,7 +2,7 @@ import EventEmitter from "eventemitter3";
import { EnforceObjectType } from "./utils";
interface IKeybind {
key: KeyboardEvent["code"] | "LCLICK" | "RCLICK" | "MCLICK";
key: KeyboardEvent["code"] | "LCLICK" | "RCLICK" | "MCLICK" | "LONG_PRESS";
alt?: boolean;
ctrl?: boolean;
@ -15,13 +15,16 @@ interface EmittedKeybind {
clientY: number;
}
export const enforceObjectType: EnforceObjectType<IKeybind> = (v) => v;
export const enforceObjectType: EnforceObjectType<IKeybind[]> = (v) => v;
const KEYBINDS = enforceObjectType({
PIXEL_WHOIS: {
key: "LCLICK",
shift: true,
},
PIXEL_WHOIS: [
{
key: "LCLICK",
shift: true,
},
{ key: "LONG_PRESS" },
],
});
class KeybindManager_ extends EventEmitter<{
@ -98,18 +101,23 @@ class KeybindManager_ extends EventEmitter<{
handleInteraction(key: IKeybind, emit: EmittedKeybind): boolean {
let isHandled = false;
for (const [name_, keybind] of Object.entries(KEYBINDS)) {
for (const [name_, keybinds] of Object.entries(KEYBINDS)) {
const name: keyof typeof KEYBINDS = name_ as any;
if (keybind.key !== key.key) continue;
if (typeof keybind.alt !== "undefined" && keybind.alt !== key.alt)
continue;
if (typeof keybind.ctrl !== "undefined" && keybind.ctrl !== key.ctrl)
continue;
if (typeof keybind.meta !== "undefined" && keybind.meta !== key.meta)
continue;
if (typeof keybind.shift !== "undefined" && keybind.shift !== key.shift)
continue;
const valid = keybinds.find((kb) => {
if (kb.key !== key.key) return false;
if (typeof kb.alt !== "undefined" && kb.alt !== key.alt) return false;
if (typeof kb.ctrl !== "undefined" && kb.ctrl !== key.ctrl)
return false;
if (typeof kb.meta !== "undefined" && kb.meta !== key.meta)
return false;
if (typeof kb.shift !== "undefined" && kb.shift !== key.shift)
return false;
return true;
});
if (!valid) continue;
this.emit(name, emit);
isHandled = true;

View File

@ -112,6 +112,7 @@ export interface ViewportMoveEvent {
}
interface PanZoomEvents {
longPress: (x: number, y: number) => void;
doubleTap: (e: TouchEvent) => void;
click: (e: ClickEvent) => void;
hover: (e: HoverEvent) => void;
@ -311,6 +312,8 @@ export class PanZoom extends EventEmitter<PanZoomEvents> {
* @param e
*/
private _touch_touchstart = (event: TouchEvent) => {
event.preventDefault();
const isDoubleTap =
this.touch.lastTouch && +new Date() - this.touch.lastTouch < 200;
@ -359,6 +362,16 @@ export class PanZoom extends EventEmitter<PanZoomEvents> {
* @param e
*/
private _touch_touchend = (event: TouchEvent) => {
if (this.touch.lastTouch && this.panning.enabled) {
const touch = event.changedTouches[0];
const dx = Math.abs(this.panning.x - touch.clientX);
const dy = Math.abs(this.panning.y - touch.clientY);
if (Date.now() - this.touch.lastTouch > 500 && dx < 25 && dy < 25) {
this.emit("longPress", this.panning.x, this.panning.y);
}
}
if (this.panning.enabled) {
this.panning.enabled = false;