Skip to content

Commit

Permalink
feat: 优化事件处理 & 修复多按键 shortcut 也能对触发的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
Houfeng committed Aug 6, 2022
1 parent 50b658c commit ca7327b
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 41 deletions.
76 changes: 51 additions & 25 deletions src/core/FingerCompose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
FingerKeyboardContext,
FingerPointerContext,
} from "./FingerContext";
import { FingerProvider, getAllFingerProviders } from "./FingerProviders";
import {
HostEvents,
HostKeyboardEvent,
Expand All @@ -16,16 +17,17 @@ import {
HostPointerEventListener,
} from "./FingerHostEvents";

import { FingerKeyboardEvents } from "./FingerKeyboardEvents";
import { FingerPointerEvents } from "./FingerPointerEvents";
import { getAllFingerProviders } from "./FingerProviders";

export type FingerMixEvents<T extends Element = Element> = HostEvents<T> &
FingerPointerEvents<T> &
FingerKeyboardEvents;
import { FingerMixEvents } from "./FingerMixEvents";

const providers = getAllFingerProviders();

function shouldTrigger(
provider: FingerProvider,
events: Partial<FingerMixEvents>
) {
return provider.events.some((it) => !!events[it as keyof FingerMixEvents]);
}

/**
* 创建包含合成处理逻辑的 PointerDown Listener
* @param events
Expand All @@ -38,12 +40,16 @@ function createPointerDownListener(
): HostPointerEventListener {
return (pointer: HostPointerEvent) => {
events.onPointerDown?.(pointer);
providers.forEach((it) =>
it.handlePointerWillDown?.({ events, context, pointer })
providers.forEach(
(it) =>
shouldTrigger(it, events) &&
it.handlePointerWillDown?.({ events, context, pointer })
);
context.addPointer(pointer);
providers.forEach((it) =>
it.handlePointerDown?.({ events, context, pointer })
providers.forEach(
(it) =>
shouldTrigger(it, events) &&
it.handlePointerDown?.({ events, context, pointer })
);
};
}
Expand All @@ -61,12 +67,16 @@ function createPointerMoveListener(
return (pointer: HostPointerEvent) => {
events.onPointerMove?.(pointer);
if (context.getPointers().length < 1) return;
providers.forEach((it) =>
it.handlePointerWillMove?.({ events, context, pointer })
providers.forEach(
(it) =>
shouldTrigger(it, events) &&
it.handlePointerWillMove?.({ events, context, pointer })
);
context.updatePointer(pointer);
providers.forEach((it) =>
it.handlePointerMove?.({ events, context, pointer })
providers.forEach(
(it) =>
shouldTrigger(it, events) &&
it.handlePointerMove?.({ events, context, pointer })
);
};
}
Expand All @@ -83,12 +93,16 @@ function createPointerUpListener(
): HostPointerEventListener {
return (pointer: HostPointerEvent) => {
events.onPointerUp?.(pointer);
providers.forEach((it) =>
it.handlePointerWillUp?.({ events, context, pointer })
providers.forEach(
(it) =>
shouldTrigger(it, events) &&
it.handlePointerWillUp?.({ events, context, pointer })
);
context.removePointer(pointer);
providers.forEach((it) =>
it.handlePointerUp?.({ events, context, pointer })
providers.forEach(
(it) =>
shouldTrigger(it, events) &&
it.handlePointerUp?.({ events, context, pointer })
);
};
}
Expand All @@ -105,12 +119,16 @@ function createPointerCancelListener(
): HostPointerEventListener {
return (pointer: HostPointerEvent) => {
events.onPointerCancel?.(pointer);
providers.forEach((it) =>
it.handlePointerWillCancel?.({ events, context, pointer })
providers.forEach(
(it) =>
shouldTrigger(it, events) &&
it.handlePointerWillCancel?.({ events, context, pointer })
);
context.removePointer(pointer);
providers.forEach((it) =>
it.handlePointerCancel?.({ events, context, pointer })
providers.forEach(
(it) =>
shouldTrigger(it, events) &&
it.handlePointerCancel?.({ events, context, pointer })
);
};
}
Expand All @@ -127,7 +145,11 @@ function createKeyDownListener(
): HostKeyboardEventListener {
return (event: HostKeyboardEvent) => {
events.onKeyDown?.(event);
providers.forEach((it) => it.handleKeyDown?.({ events, context, event }));
providers.forEach(
(it) =>
shouldTrigger(it, events) &&
it.handleKeyDown?.({ events, context, event })
);
};
}

Expand All @@ -143,7 +165,11 @@ function createKeyUpListener(
): HostKeyboardEventListener {
return (event: HostKeyboardEvent) => {
events.onKeyUp?.(event);
providers.forEach((it) => it.handleKeyUp?.({ events, context, event }));
providers.forEach(
(it) =>
shouldTrigger(it, events) &&
it.handleKeyUp?.({ events, context, event })
);
};
}

Expand Down
12 changes: 12 additions & 0 deletions src/core/FingerMixEvents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* @homepage https://github.com/Houfeng/react-finger
* @author Houfeng <houzhanfeng@gmail.com>
*/

import { FingerKeyboardEvents } from "./FingerKeyboardEvents";
import { FingerPointerEvents } from "./FingerPointerEvents";
import { HostEvents } from "./FingerHostEvents";

export type FingerMixEvents<T extends Element = Element> = HostEvents<T> &
FingerPointerEvents<T> &
FingerKeyboardEvents;
12 changes: 8 additions & 4 deletions src/events/FingerBasicProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,39 @@ export const FingerBasicProvider: FingerProvider = {
events: ["onFingerDown", "onFingerMove", "onFingerUp", "onFingerCancel"],

handlePointerDown: ({ events, context, pointer }) => {
if (!events.onFingerDown) return;
const { getPointers, getChangedPointers } = context;
const pointers = getPointers();
const changedPointers = getChangedPointers();
const detail = { pointers, changedPointers };
events.onFingerDown?.(FingerPointerEvent("onFingerDown", pointer, detail));
events.onFingerDown(FingerPointerEvent("onFingerDown", pointer, detail));
},

handlePointerMove: ({ events, context, pointer }) => {
if (!events.onFingerMove) return;
const { getPointers, getChangedPointers } = context;
const pointers = getPointers();
const changedPointers = getChangedPointers();
const detail = { pointers, changedPointers };
events.onFingerMove?.(FingerPointerEvent("onFingerMove", pointer, detail));
events.onFingerMove(FingerPointerEvent("onFingerMove", pointer, detail));
},

handlePointerUp: ({ events, context, pointer }) => {
if (!events.onFingerUp) return;
const { getPointers, getChangedPointers } = context;
const pointers = getPointers();
const changedPointers = getChangedPointers();
const detail = { pointers, changedPointers };
events.onFingerUp?.(FingerPointerEvent("onFingerUp", pointer, detail));
events.onFingerUp(FingerPointerEvent("onFingerUp", pointer, detail));
},

handlePointerCancel: ({ events, context, pointer }) => {
if (!events.onFingerCancel) return;
const { getPointers, getChangedPointers } = context;
const pointers = getPointers();
const changedPointers = getChangedPointers();
const detail = { pointers, changedPointers };
events.onFingerCancel?.(
events.onFingerCancel(
FingerPointerEvent("onFingerCancel", pointer, detail)
);
},
Expand Down
10 changes: 6 additions & 4 deletions src/events/FingerShortcutProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ export const FingerShortcutProvider: FingerProvider = {

handleKeyDown: ({ events, context, event }) => {
const { flags } = context;
const keySet = flags.has(KEY_SET)
const set = flags.has(KEY_SET)
? (flags.get(KEY_SET) as Set<string>)
: new Set<string>();
if (!flags.has(KEY_SET)) flags.set(KEY_SET, keySet);
keySet.add(event.key.toLowerCase());
if (!flags.has(KEY_SET)) flags.set(KEY_SET, set);
set.add(event.key.toLowerCase());
const when: FingerShortcutEvent["detail"]["when"] = (keys, handler) => {
if (keys.every((key) => keySet.has(key))) handler();
if (keys.length === set.size && keys.every((key) => set.has(key))) {
handler();
}
};
const shortcutEvent = FingerKeyboardEvent("onShortcut", event, { when });
events.onShortcut?.(shortcutEvent);
Expand Down
3 changes: 2 additions & 1 deletion src/helpers/FingerFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
* @author Houfeng <houzhanfeng@gmail.com>
*/

import { FingerMixEvents, composeFingerEvents } from "../core/FingerCompose";
import { FingerMixEvents } from "../core/FingerMixEvents";
import { composeFingerEvents } from "../core/FingerCompose";

/**
* 通过「方法」创建可用于 element 的 events,通常用于类组件,
Expand Down
2 changes: 1 addition & 1 deletion src/helpers/FingerHoC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { HTMLAttributes, ReactNode, createElement, forwardRef } from "react";

import { FingerMixEvents } from "../core/FingerCompose";
import { FingerMixEvents } from "../core/FingerMixEvents";
import { getAllEventNames } from "../core/FingerProviders";
import { useFingerEvents } from "./FingerHook";

Expand Down
4 changes: 3 additions & 1 deletion src/helpers/FingerHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
* @author Houfeng <houzhanfeng@gmail.com>
*/

import { FingerMixEvents, composeFingerEvents } from "../core/FingerCompose";
import { useLayoutEffect, useMemo } from "react";

import { FingerMixEvents } from "../core/FingerMixEvents";
import { composeFingerEvents } from "../core/FingerCompose";

/**
* 通过 hook 创建可用于 element 的 events
* 注意:此 hook 返回稳定引用的同时会自动更新处理函数中的依赖,不会造成不必要的渲染
Expand Down
2 changes: 1 addition & 1 deletion src/helpers/FingerProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {

import { AnyFunction } from "../core/FingerUtils";
import { EventEmitter } from "eify";
import { FingerMixEvents } from "../core/FingerCompose";
import { FingerMixEvents } from "../core/FingerMixEvents";
import { HostEvents } from "../core/FingerHostEvents";
import { useFingerEvents } from "./FingerHook";

Expand Down
7 changes: 3 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ export {
type FingerShortcutEvent,
} from "./core/FingerKeyboardEvents";

export {
type FingerMixEvents,
composeFingerEvents,
} from "./core/FingerCompose";
export { composeFingerEvents } from "./core/FingerCompose";

export { type FingerMixEvents } from "./core/FingerMixEvents";

export { FingerOptions } from "./core/FingerOptions";

Expand Down

0 comments on commit ca7327b

Please sign in to comment.