pxd 0.0.63 → 0.0.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/avatar/index.d.vue.ts +2 -2
- package/dist/components/badge/index.d.vue.ts +1 -1
- package/dist/components/hold-button/index.d.vue.ts +4 -4
- package/dist/components/input/index.d.vue.ts +8 -8
- package/dist/components/link-button/index.d.vue.ts +1 -1
- package/dist/components/list-item/index.d.vue.ts +1 -1
- package/dist/components/number-input/index.d.vue.ts +2 -2
- package/dist/components/pin-input/index.d.vue.ts +1 -1
- package/dist/components/scrollable/index.d.vue.ts +2 -2
- package/dist/components/textarea/index.d.vue.ts +2 -2
- package/dist/composables/use-swipe-gesture.js +1 -2
- package/dist/plugins/any-touch.d.ts +213 -0
- package/dist/plugins/any-touch.js +592 -0
- package/package.json +1 -3
|
@@ -9,12 +9,12 @@ type __VLS_Slots = {} & {
|
|
|
9
9
|
declare const __VLS_base: import("vue").DefineComponent<AvatarProps, {
|
|
10
10
|
getLoadingStatus: typeof getLoadingStatus;
|
|
11
11
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
12
|
-
load: (args_0: Event) => any;
|
|
13
12
|
error: (args_0: Event) => any;
|
|
13
|
+
load: (args_0: Event) => any;
|
|
14
14
|
loadstart: (args_0: Event) => any;
|
|
15
15
|
}, string, import("vue").PublicProps, Readonly<AvatarProps> & Readonly<{
|
|
16
|
-
onLoad?: ((args_0: Event) => any) | undefined;
|
|
17
16
|
onError?: ((args_0: Event) => any) | undefined;
|
|
17
|
+
onLoad?: ((args_0: Event) => any) | undefined;
|
|
18
18
|
onLoadstart?: ((args_0: Event) => any) | undefined;
|
|
19
19
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
20
20
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
@@ -8,8 +8,8 @@ declare const __VLS_base: import("vue").DefineComponent<BadgeProps, {}, {}, {},
|
|
|
8
8
|
}, string, import("vue").PublicProps, Readonly<BadgeProps> & Readonly<{
|
|
9
9
|
onClose?: ((args_0: Event) => any) | undefined;
|
|
10
10
|
}>, {
|
|
11
|
-
as: import("../../types/shared").ComponentAs;
|
|
12
11
|
variant: import("./types").BadgeVariant;
|
|
12
|
+
as: import("../../types/shared").ComponentAs;
|
|
13
13
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
14
14
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
15
15
|
declare const _default: typeof __VLS_export;
|
|
@@ -9,16 +9,16 @@ type __VLS_Slots = {} & {
|
|
|
9
9
|
};
|
|
10
10
|
declare const __VLS_base: import("vue").DefineComponent<HoldButtonProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
11
|
cancel: () => any;
|
|
12
|
+
pointerdown: (args_0: PointerEvent) => any;
|
|
13
|
+
pointerup: (args_0: PointerEvent) => any;
|
|
12
14
|
confirm: () => any;
|
|
13
15
|
release: (confirmed: boolean) => any;
|
|
14
|
-
pointerup: (args_0: PointerEvent) => any;
|
|
15
|
-
pointerdown: (args_0: PointerEvent) => any;
|
|
16
16
|
}, string, import("vue").PublicProps, Readonly<HoldButtonProps> & Readonly<{
|
|
17
17
|
onCancel?: (() => any) | undefined;
|
|
18
|
+
onPointerdown?: ((args_0: PointerEvent) => any) | undefined;
|
|
19
|
+
onPointerup?: ((args_0: PointerEvent) => any) | undefined;
|
|
18
20
|
onConfirm?: (() => any) | undefined;
|
|
19
21
|
onRelease?: ((confirmed: boolean) => any) | undefined;
|
|
20
|
-
onPointerup?: ((args_0: PointerEvent) => any) | undefined;
|
|
21
|
-
onPointerdown?: ((args_0: PointerEvent) => any) | undefined;
|
|
22
22
|
}>, {
|
|
23
23
|
vibrate: boolean;
|
|
24
24
|
scalable: boolean;
|
|
@@ -18,24 +18,24 @@ declare const __VLS_base: import("vue").DefineComponent<InputProps, {
|
|
|
18
18
|
change: (args_0: string, args_1: Event) => any;
|
|
19
19
|
"update:modelValue": (args_0: string) => any;
|
|
20
20
|
input: (args_0: string) => any;
|
|
21
|
-
click: (args_0: MouseEvent) => any;
|
|
22
|
-
keydown: (args_0: KeyboardEvent) => any;
|
|
23
|
-
focus: (args_0: FocusEvent) => any;
|
|
24
21
|
blur: (args_0: FocusEvent) => any;
|
|
22
|
+
click: (args_0: MouseEvent) => any;
|
|
23
|
+
compositionend: (args_0: CompositionEvent) => any;
|
|
25
24
|
compositionstart: (args_0: CompositionEvent) => any;
|
|
26
25
|
compositionupdate: (args_0: CompositionEvent) => any;
|
|
27
|
-
|
|
26
|
+
focus: (args_0: FocusEvent) => any;
|
|
27
|
+
keydown: (args_0: KeyboardEvent) => any;
|
|
28
28
|
}, string, import("vue").PublicProps, Readonly<InputProps> & Readonly<{
|
|
29
29
|
onChange?: ((args_0: string, args_1: Event) => any) | undefined;
|
|
30
30
|
"onUpdate:modelValue"?: ((args_0: string) => any) | undefined;
|
|
31
31
|
onInput?: ((args_0: string) => any) | undefined;
|
|
32
|
-
onClick?: ((args_0: MouseEvent) => any) | undefined;
|
|
33
|
-
onKeydown?: ((args_0: KeyboardEvent) => any) | undefined;
|
|
34
|
-
onFocus?: ((args_0: FocusEvent) => any) | undefined;
|
|
35
32
|
onBlur?: ((args_0: FocusEvent) => any) | undefined;
|
|
33
|
+
onClick?: ((args_0: MouseEvent) => any) | undefined;
|
|
34
|
+
onCompositionend?: ((args_0: CompositionEvent) => any) | undefined;
|
|
36
35
|
onCompositionstart?: ((args_0: CompositionEvent) => any) | undefined;
|
|
37
36
|
onCompositionupdate?: ((args_0: CompositionEvent) => any) | undefined;
|
|
38
|
-
|
|
37
|
+
onFocus?: ((args_0: FocusEvent) => any) | undefined;
|
|
38
|
+
onKeydown?: ((args_0: KeyboardEvent) => any) | undefined;
|
|
39
39
|
}>, {
|
|
40
40
|
align: "left" | "center" | "right";
|
|
41
41
|
defaultPrefixStyle: boolean;
|
|
@@ -12,8 +12,8 @@ declare const __VLS_base: import("vue").DefineComponent<LinkButtonProps, {}, {},
|
|
|
12
12
|
}, string, import("vue").PublicProps, Readonly<LinkButtonProps> & Readonly<{
|
|
13
13
|
onClick?: ((args_0: MouseEvent) => any) | undefined;
|
|
14
14
|
}>, {
|
|
15
|
-
align: "left" | "center" | "right";
|
|
16
15
|
target: "_blank" | "_self" | "_parent" | "_top";
|
|
16
|
+
align: "left" | "center" | "right";
|
|
17
17
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
18
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
19
19
|
declare const _default: typeof __VLS_export;
|
|
@@ -8,8 +8,8 @@ declare const __VLS_base: import("vue").DefineComponent<ListItemProps, {}, {}, {
|
|
|
8
8
|
}, string, import("vue").PublicProps, Readonly<ListItemProps> & Readonly<{
|
|
9
9
|
onClick?: ((args_0: import("../list/types").ListOptionSelected, args_1: MouseEvent) => any) | undefined;
|
|
10
10
|
}>, {
|
|
11
|
+
type: "error" | "default" | "warning";
|
|
11
12
|
disabled: boolean;
|
|
12
|
-
type: "default" | "error" | "warning";
|
|
13
13
|
as: import("../../types/shared").ComponentAs;
|
|
14
14
|
keywords: string[];
|
|
15
15
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -13,14 +13,14 @@ declare const __VLS_base: import("vue").DefineComponent<NumberInputProps, {}, {}
|
|
|
13
13
|
change: (args_0: number | null | undefined, args_1: Event) => any;
|
|
14
14
|
"update:modelValue": (args_0: number | null | undefined) => any;
|
|
15
15
|
input: (args_0: number | null | undefined) => any;
|
|
16
|
-
focus: (args_0: FocusEvent) => any;
|
|
17
16
|
blur: (args_0: FocusEvent) => any;
|
|
17
|
+
focus: (args_0: FocusEvent) => any;
|
|
18
18
|
}, string, import("vue").PublicProps, Readonly<NumberInputProps> & Readonly<{
|
|
19
19
|
onChange?: ((args_0: number | null | undefined, args_1: Event) => any) | undefined;
|
|
20
20
|
"onUpdate:modelValue"?: ((args_0: number | null | undefined) => any) | undefined;
|
|
21
21
|
onInput?: ((args_0: number | null | undefined) => any) | undefined;
|
|
22
|
-
onFocus?: ((args_0: FocusEvent) => any) | undefined;
|
|
23
22
|
onBlur?: ((args_0: FocusEvent) => any) | undefined;
|
|
23
|
+
onFocus?: ((args_0: FocusEvent) => any) | undefined;
|
|
24
24
|
}>, {
|
|
25
25
|
max: number;
|
|
26
26
|
min: number;
|
|
@@ -12,8 +12,8 @@ declare const __VLS_export: import("vue").DefineComponent<PinInputProps, {
|
|
|
12
12
|
"onUpdate:modelValue"?: ((args_0: string) => any) | undefined;
|
|
13
13
|
}>, {
|
|
14
14
|
modelValue: string;
|
|
15
|
-
length: number;
|
|
16
15
|
type: "numeric" | "alphabetic" | "alphanumeric" | "numeric-password" | "alphabetic-password" | "alphanumeric-password";
|
|
16
|
+
length: number;
|
|
17
17
|
placeholder: string;
|
|
18
18
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
19
19
|
declare const _default: typeof __VLS_export;
|
|
@@ -9,11 +9,11 @@ declare const __VLS_base: import("vue").DefineComponent<ScrollableProps, {
|
|
|
9
9
|
scrollTo: typeof scrollTo;
|
|
10
10
|
forceUpdate: typeof forceUpdate;
|
|
11
11
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
12
|
-
bottom: (args_0: import("../../types/shared").ComponentDirection, args_1: Event) => any;
|
|
13
12
|
scroll: (args_0: Event) => any;
|
|
13
|
+
bottom: (args_0: import("../../types/shared").ComponentDirection, args_1: Event) => any;
|
|
14
14
|
}, string, import("vue").PublicProps, Readonly<ScrollableProps> & Readonly<{
|
|
15
|
-
onBottom?: ((args_0: import("../../types/shared").ComponentDirection, args_1: Event) => any) | undefined;
|
|
16
15
|
onScroll?: ((args_0: Event) => any) | undefined;
|
|
16
|
+
onBottom?: ((args_0: import("../../types/shared").ComponentDirection, args_1: Event) => any) | undefined;
|
|
17
17
|
}>, {
|
|
18
18
|
fader: boolean;
|
|
19
19
|
scrollbar: boolean;
|
|
@@ -2,13 +2,13 @@ import type { TextareaProps } from './types';
|
|
|
2
2
|
declare const __VLS_export: import("vue").DefineComponent<TextareaProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
3
3
|
change: (args_0: NonNullable<import("../../types/shared").ComponentLabel | undefined>) => any;
|
|
4
4
|
"update:modelValue": (args_0: NonNullable<import("../../types/shared").ComponentLabel | undefined>) => any;
|
|
5
|
-
focus: (args_0: FocusEvent) => any;
|
|
6
5
|
blur: (args_0: FocusEvent) => any;
|
|
6
|
+
focus: (args_0: FocusEvent) => any;
|
|
7
7
|
}, string, import("vue").PublicProps, Readonly<TextareaProps> & Readonly<{
|
|
8
8
|
onChange?: ((args_0: NonNullable<import("../../types/shared").ComponentLabel | undefined>) => any) | undefined;
|
|
9
9
|
"onUpdate:modelValue"?: ((args_0: NonNullable<import("../../types/shared").ComponentLabel | undefined>) => any) | undefined;
|
|
10
|
-
onFocus?: ((args_0: FocusEvent) => any) | undefined;
|
|
11
10
|
onBlur?: ((args_0: FocusEvent) => any) | undefined;
|
|
11
|
+
onFocus?: ((args_0: FocusEvent) => any) | undefined;
|
|
12
12
|
}>, {
|
|
13
13
|
modelValue: import("../../types/shared").ComponentLabel;
|
|
14
14
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import Core from "@any-touch/core";
|
|
2
|
-
import Pan from "@any-touch/pan";
|
|
3
1
|
import { onScopeDispose, watch } from "vue";
|
|
2
|
+
import { Core, Pan } from "../plugins/any-touch.js";
|
|
4
3
|
import { toValue, unrefElement } from "../utils/ref.js";
|
|
5
4
|
export function useSwipeGesture(containerRef, options = {}) {
|
|
6
5
|
const {
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
type KV = Record<string, any>;
|
|
2
|
+
type SupportElement = HTMLElement | SVGElement;
|
|
3
|
+
/** 输入阶段 */
|
|
4
|
+
type phase = 'start' | 'move' | 'end' | 'cancel';
|
|
5
|
+
/** 方向 */
|
|
6
|
+
type directionString = 'up' | 'right' | 'down' | 'left' | 'none';
|
|
7
|
+
/** 点 */
|
|
8
|
+
interface Point {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
}
|
|
12
|
+
type Vector = Point;
|
|
13
|
+
interface PointClientXY {
|
|
14
|
+
target: EventTarget | null;
|
|
15
|
+
clientX: number;
|
|
16
|
+
clientY: number;
|
|
17
|
+
}
|
|
18
|
+
/** 原生事件上选取的共有字段 */
|
|
19
|
+
interface PubicEvent {
|
|
20
|
+
readonly phase: phase;
|
|
21
|
+
readonly changedPoints: PointClientXY[];
|
|
22
|
+
readonly points: PointClientXY[];
|
|
23
|
+
readonly target: EventTarget | null;
|
|
24
|
+
readonly targets: (EventTarget | null)[];
|
|
25
|
+
readonly nativeEvent: Event;
|
|
26
|
+
}
|
|
27
|
+
/** 不包含prevInput/startInput/startMultiInput的Input */
|
|
28
|
+
interface InputOnlyHasCurrent extends PubicEvent {
|
|
29
|
+
readonly id: number;
|
|
30
|
+
readonly isStart: boolean;
|
|
31
|
+
readonly isEnd: boolean;
|
|
32
|
+
readonly pointLength: number;
|
|
33
|
+
readonly timestamp: number;
|
|
34
|
+
readonly currentTarget: EventTarget | null;
|
|
35
|
+
readonly center?: Point;
|
|
36
|
+
readonly x: number;
|
|
37
|
+
readonly y: number;
|
|
38
|
+
readonly getOffset: (el: HTMLElement) => {
|
|
39
|
+
x: number;
|
|
40
|
+
y: number;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** 提供给插件(compute函数)之前的统一化数据 */
|
|
44
|
+
interface Input extends InputOnlyHasCurrent {
|
|
45
|
+
readonly startInput: InputOnlyHasCurrent;
|
|
46
|
+
readonly startMultiInput?: InputOnlyHasCurrent;
|
|
47
|
+
readonly prevInput?: InputOnlyHasCurrent;
|
|
48
|
+
}
|
|
49
|
+
/** Input执行计算后的数据格式 */
|
|
50
|
+
interface Computed extends KV {
|
|
51
|
+
readonly maxPointLength?: number;
|
|
52
|
+
readonly velocityX?: number;
|
|
53
|
+
readonly velocityY?: number;
|
|
54
|
+
readonly speedX?: number;
|
|
55
|
+
readonly speedY?: number;
|
|
56
|
+
readonly scale?: number;
|
|
57
|
+
readonly deltaScale?: number;
|
|
58
|
+
readonly angle?: number;
|
|
59
|
+
readonly deltaAngle?: number;
|
|
60
|
+
readonly deltaX?: number;
|
|
61
|
+
readonly deltaY?: number;
|
|
62
|
+
readonly deltaXYAngle?: number;
|
|
63
|
+
readonly displacementX?: number;
|
|
64
|
+
readonly displacementY?: number;
|
|
65
|
+
readonly distanceX?: number;
|
|
66
|
+
readonly distanceY?: number;
|
|
67
|
+
readonly distance?: number;
|
|
68
|
+
readonly deltaTime?: number;
|
|
69
|
+
readonly overallDirection?: directionString;
|
|
70
|
+
readonly direction?: directionString;
|
|
71
|
+
readonly startVecotr?: Vector;
|
|
72
|
+
readonly prevVecotr?: Vector;
|
|
73
|
+
readonly activeVecotr?: Vector;
|
|
74
|
+
}
|
|
75
|
+
interface AnyTouchEvent extends Input, Required<Computed> {
|
|
76
|
+
readonly type: string;
|
|
77
|
+
readonly stopPropagation: () => void;
|
|
78
|
+
readonly stopImmediatePropagation: () => void;
|
|
79
|
+
readonly preventDefault: () => void;
|
|
80
|
+
}
|
|
81
|
+
/** 适配器支持的事件类型 */
|
|
82
|
+
type NativeEvent = MouseEvent | TouchEvent;
|
|
83
|
+
interface Options {
|
|
84
|
+
domEvents?: false | EventInit;
|
|
85
|
+
preventDefault?: boolean | ((e: NativeEvent) => boolean);
|
|
86
|
+
}
|
|
87
|
+
/** 计算函数 */
|
|
88
|
+
type ComputeFunction = (input: Input, computed: Partial<Computed>) => Computed | void;
|
|
89
|
+
/** 计算函数生成器 */
|
|
90
|
+
type ComputeFunctionCreator = () => ComputeFunction;
|
|
91
|
+
/** 识别器状态 */
|
|
92
|
+
declare const STATE: {
|
|
93
|
+
readonly POSSIBLE: 0;
|
|
94
|
+
readonly RECOGNIZED: 1;
|
|
95
|
+
readonly FAILED: 2;
|
|
96
|
+
readonly CANCELLED: 3;
|
|
97
|
+
readonly START: 4;
|
|
98
|
+
readonly MOVE: 5;
|
|
99
|
+
readonly END: 1;
|
|
100
|
+
};
|
|
101
|
+
type STATE = (typeof STATE)[keyof typeof STATE];
|
|
102
|
+
type RECOGNIZER_STATE = STATE;
|
|
103
|
+
type PluginOptions = {
|
|
104
|
+
name?: string;
|
|
105
|
+
} & KV;
|
|
106
|
+
type PluginContext<D extends Required<PluginOptions> = Required<PluginOptions>> = {
|
|
107
|
+
state: RECOGNIZER_STATE;
|
|
108
|
+
disabled: boolean;
|
|
109
|
+
} & D;
|
|
110
|
+
type Plugin = (context: Core, pluginOptions?: PluginOptions) => PluginContext;
|
|
111
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
112
|
+
interface DefaultTypeAndEventMap {
|
|
113
|
+
[type: string]: any;
|
|
114
|
+
}
|
|
115
|
+
type AEventListener<Event, Key> = (event: Event, key: Key) => void;
|
|
116
|
+
interface Interceptor {
|
|
117
|
+
(type: string | number | symbol, next: () => void): void;
|
|
118
|
+
}
|
|
119
|
+
interface PluginContextMap {
|
|
120
|
+
pan: PanContext;
|
|
121
|
+
}
|
|
122
|
+
interface EventMap {
|
|
123
|
+
input: Input;
|
|
124
|
+
computed: Record<string, any>;
|
|
125
|
+
u: undefined;
|
|
126
|
+
'at:after': Computed;
|
|
127
|
+
'at:start': Input;
|
|
128
|
+
'at:move': Input;
|
|
129
|
+
'at:cancel': Input;
|
|
130
|
+
'at:end': Input;
|
|
131
|
+
pan: AnyTouchEvent;
|
|
132
|
+
panstart: AnyTouchEvent;
|
|
133
|
+
panmove: AnyTouchEvent;
|
|
134
|
+
panend: AnyTouchEvent;
|
|
135
|
+
pancancel: AnyTouchEvent;
|
|
136
|
+
panup: AnyTouchEvent;
|
|
137
|
+
pandown: AnyTouchEvent;
|
|
138
|
+
panright: AnyTouchEvent;
|
|
139
|
+
panleft: AnyTouchEvent;
|
|
140
|
+
}
|
|
141
|
+
type GetPluginContext<N> = N extends keyof PluginContextMap ? PluginContextMap[N] : PluginContext | undefined;
|
|
142
|
+
type PanContext = PluginContext & typeof PAN_DEFAULT_OPTIONS;
|
|
143
|
+
declare const PAN_DEFAULT_OPTIONS: {
|
|
144
|
+
name: string;
|
|
145
|
+
threshold: number;
|
|
146
|
+
pointLength: number;
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* ========================================
|
|
150
|
+
* AnyEvent 基类 (来自 any-event)
|
|
151
|
+
* ========================================
|
|
152
|
+
*/
|
|
153
|
+
declare class AnyEvent<TypeAndEventMap extends DefaultTypeAndEventMap = DefaultTypeAndEventMap> {
|
|
154
|
+
private __map;
|
|
155
|
+
private __interceptor?;
|
|
156
|
+
/** 当前事件对象 */
|
|
157
|
+
event: unknown;
|
|
158
|
+
/** 注册拦截器 */
|
|
159
|
+
beforeEach(interceptor: Interceptor): void;
|
|
160
|
+
/** 绑定事件 */
|
|
161
|
+
on<Key extends keyof TypeAndEventMap>(typeOrTypes: Key | Key[], listener: AEventListener<TypeAndEventMap[Key], Key>): this;
|
|
162
|
+
/** 触发事件 */
|
|
163
|
+
emit<Key extends keyof TypeAndEventMap>(type: Key, payload?: TypeAndEventMap[Key], callback?: () => void): void;
|
|
164
|
+
private __doEmit;
|
|
165
|
+
/** 解除绑定 */
|
|
166
|
+
off<Key extends keyof TypeAndEventMap>(type: Key, listener?: AEventListener<TypeAndEventMap[Key], Key>): void;
|
|
167
|
+
/** 销毁实例 */
|
|
168
|
+
destroy(): void;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* ========================================
|
|
172
|
+
* Core 核心类 (来自 @any-touch/core)
|
|
173
|
+
* ========================================
|
|
174
|
+
*/
|
|
175
|
+
declare class Core extends AnyEvent<EventMap> {
|
|
176
|
+
/** 版本 */
|
|
177
|
+
v: string;
|
|
178
|
+
/** 当前绑定元素 */
|
|
179
|
+
el?: SupportElement;
|
|
180
|
+
/** 当前插件上下文 */
|
|
181
|
+
c?: PluginContext;
|
|
182
|
+
private __options;
|
|
183
|
+
private __inputCreatorMap;
|
|
184
|
+
private __computeFunctionList;
|
|
185
|
+
private __computeFunctionCreatorList;
|
|
186
|
+
private __pluginContexts;
|
|
187
|
+
private __isIgnoreMouse;
|
|
188
|
+
constructor(el?: SupportElement, options?: Options);
|
|
189
|
+
/** 加载并初始化插件 */
|
|
190
|
+
use<P extends Plugin>(plugin: P, pluginOptions?: Parameters<P>[1]): void;
|
|
191
|
+
/** 监听input变化 */
|
|
192
|
+
catchEvent(event: NativeEvent): void;
|
|
193
|
+
/** 缓存计算函数生成器到队列 */
|
|
194
|
+
compute<CList extends ComputeFunctionCreator[] = ComputeFunctionCreator[]>(computeFunctionCreatorList: CList, callback: (computed: UnionToIntersection<ReturnType<ReturnType<CList[0]>>> & Input) => void): void;
|
|
195
|
+
/** 拦截器 */
|
|
196
|
+
beforeEach(interceptor: (type: string, next: () => void) => void): void;
|
|
197
|
+
/** 获取识别器通过名字 */
|
|
198
|
+
get<N extends keyof PluginContextMap>(name: N): GetPluginContext<N>;
|
|
199
|
+
/** 设置选项 */
|
|
200
|
+
set(newOptions: Partial<Options>): void;
|
|
201
|
+
/** 带DOM事件的emit */
|
|
202
|
+
emit2(type: string, payload: Computed, pluginContext: PluginContext): void;
|
|
203
|
+
/** 销毁 */
|
|
204
|
+
destroy(): void;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* ========================================
|
|
208
|
+
* Pan 识别器 (来自 @any-touch/pan)
|
|
209
|
+
* ========================================
|
|
210
|
+
*/
|
|
211
|
+
/** "拖拽"识别器 */
|
|
212
|
+
declare function Pan(at: Core, options?: Partial<typeof PAN_DEFAULT_OPTIONS>): PanContext;
|
|
213
|
+
export { Core, Pan };
|
|
@@ -0,0 +1,592 @@
|
|
|
1
|
+
const STATE = {
|
|
2
|
+
POSSIBLE: 0,
|
|
3
|
+
RECOGNIZED: 1,
|
|
4
|
+
FAILED: 2,
|
|
5
|
+
CANCELLED: 3,
|
|
6
|
+
START: 4,
|
|
7
|
+
MOVE: 5,
|
|
8
|
+
END: 1
|
|
9
|
+
};
|
|
10
|
+
const CLIENT_X = "clientX";
|
|
11
|
+
const CLIENT_Y = "clientY";
|
|
12
|
+
const PHASE_START = "start";
|
|
13
|
+
const DIRECTION_LEFT = "left";
|
|
14
|
+
const DIRECTION_RIGHT = "right";
|
|
15
|
+
const DIRECTION_DOWN = "down";
|
|
16
|
+
const STATE_MAP = {
|
|
17
|
+
[STATE.START]: "start",
|
|
18
|
+
[STATE.MOVE]: "move",
|
|
19
|
+
[STATE.END]: "end",
|
|
20
|
+
[STATE.CANCELLED]: "cancel"
|
|
21
|
+
};
|
|
22
|
+
const TOUCH_EVENTS = ["touchstart", "touchmove", "touchend", "touchcancel", "mousedown"];
|
|
23
|
+
const MOUSE_EVENTS = ["mousemove", "mouseup"];
|
|
24
|
+
const DEFAULT_OPTIONS = {
|
|
25
|
+
domEvents: { bubbles: true, cancelable: true },
|
|
26
|
+
preventDefault: (e) => {
|
|
27
|
+
if (e.target && "tagName" in e.target) {
|
|
28
|
+
const { tagName } = e.target;
|
|
29
|
+
return !/^(?:INPUT|TEXTAREA|BUTTON|SELECT)$/.test(tagName);
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const PAN_DEFAULT_OPTIONS = {
|
|
35
|
+
name: "pan",
|
|
36
|
+
threshold: 10,
|
|
37
|
+
pointLength: 1
|
|
38
|
+
};
|
|
39
|
+
function stateToPhase(state) {
|
|
40
|
+
return STATE_MAP[state];
|
|
41
|
+
}
|
|
42
|
+
function computeFSM(isRecognized, state, phase) {
|
|
43
|
+
const table = {
|
|
44
|
+
// 已识别
|
|
45
|
+
1: {
|
|
46
|
+
0: { move: STATE.START },
|
|
47
|
+
4: { move: STATE.MOVE, end: STATE.END, cancel: STATE.CANCELLED },
|
|
48
|
+
5: { move: STATE.MOVE, end: STATE.END, cancel: STATE.CANCELLED }
|
|
49
|
+
},
|
|
50
|
+
// 未识别
|
|
51
|
+
0: {
|
|
52
|
+
4: { move: STATE.RECOGNIZED, end: STATE.END, cancel: STATE.CANCELLED },
|
|
53
|
+
5: {
|
|
54
|
+
start: STATE.RECOGNIZED,
|
|
55
|
+
move: STATE.RECOGNIZED,
|
|
56
|
+
end: STATE.END,
|
|
57
|
+
cancel: STATE.CANCELLED
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const transitions = table[Number(isRecognized)]?.[state];
|
|
62
|
+
return transitions !== void 0 && transitions[phase] || 0;
|
|
63
|
+
}
|
|
64
|
+
function resetIfTerminalState(context) {
|
|
65
|
+
if ([STATE.END, STATE.CANCELLED, STATE.FAILED].includes(context.state)) {
|
|
66
|
+
context.state = STATE.POSSIBLE;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function isEndOrCancelState(state) {
|
|
70
|
+
return [STATE.MOVE, STATE.END, STATE.CANCELLED].includes(state);
|
|
71
|
+
}
|
|
72
|
+
function abortIfDisabled(context) {
|
|
73
|
+
if (context.disabled) {
|
|
74
|
+
context.state = STATE.POSSIBLE;
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function createPluginContext(defaults, options) {
|
|
79
|
+
return { ...defaults, ...options, state: STATE.POSSIBLE, disabled: false };
|
|
80
|
+
}
|
|
81
|
+
function vectorLength(v) {
|
|
82
|
+
return Math.sqrt(v.x * v.x + v.y * v.y);
|
|
83
|
+
}
|
|
84
|
+
function radToDeg(rad) {
|
|
85
|
+
return rad / Math.PI * 180;
|
|
86
|
+
}
|
|
87
|
+
function computeDirection(deltaX, deltaY) {
|
|
88
|
+
if (deltaX !== 0 || deltaY !== 0) {
|
|
89
|
+
return Math.abs(deltaX) >= Math.abs(deltaY) ? deltaX > 0 ? DIRECTION_RIGHT : DIRECTION_LEFT : deltaY > 0 ? DIRECTION_DOWN : "up";
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
class AnyEvent {
|
|
93
|
+
__map = {};
|
|
94
|
+
__interceptor;
|
|
95
|
+
/** 当前事件对象 */
|
|
96
|
+
event;
|
|
97
|
+
/** 注册拦截器 */
|
|
98
|
+
beforeEach(interceptor) {
|
|
99
|
+
this.__interceptor = interceptor;
|
|
100
|
+
}
|
|
101
|
+
/** 绑定事件 */
|
|
102
|
+
on(typeOrTypes, listener) {
|
|
103
|
+
const types = Array.isArray(typeOrTypes) ? typeOrTypes : [typeOrTypes];
|
|
104
|
+
for (const type of types) {
|
|
105
|
+
this.__map[type] = this.__map[type] || [];
|
|
106
|
+
const list = this.__map[type];
|
|
107
|
+
if (list) {
|
|
108
|
+
list.push(listener);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
/** 触发事件 */
|
|
114
|
+
emit(type, payload, callback) {
|
|
115
|
+
if (this.__interceptor === void 0) {
|
|
116
|
+
this.__doEmit(type, payload);
|
|
117
|
+
callback?.();
|
|
118
|
+
} else {
|
|
119
|
+
this.__interceptor(type, () => {
|
|
120
|
+
this.__doEmit(type, payload);
|
|
121
|
+
callback?.();
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
__doEmit(type, payload) {
|
|
126
|
+
const list = this.__map[type];
|
|
127
|
+
if (Array.isArray(list) && list?.length) {
|
|
128
|
+
for (const listener of list) {
|
|
129
|
+
listener(payload, type);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
this.event = payload;
|
|
133
|
+
}
|
|
134
|
+
/** 解除绑定 */
|
|
135
|
+
off(type, listener) {
|
|
136
|
+
const list = this.__map[type];
|
|
137
|
+
if (list !== void 0) {
|
|
138
|
+
if (listener === void 0) {
|
|
139
|
+
delete this.__map[type];
|
|
140
|
+
} else {
|
|
141
|
+
const index = list.findIndex((l) => l === listener);
|
|
142
|
+
list.splice(index, 1);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/** 销毁实例 */
|
|
147
|
+
destroy() {
|
|
148
|
+
this.__map = {};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function getCenter(points) {
|
|
152
|
+
const { length } = points;
|
|
153
|
+
if (length > 0) {
|
|
154
|
+
if (length === 1) {
|
|
155
|
+
const { clientX, clientY } = points[0];
|
|
156
|
+
return { x: Math.round(clientX), y: Math.round(clientY) };
|
|
157
|
+
}
|
|
158
|
+
const sum = points.reduce(
|
|
159
|
+
(acc, p) => {
|
|
160
|
+
acc.x += p[CLIENT_X];
|
|
161
|
+
acc.y += p[CLIENT_Y];
|
|
162
|
+
return acc;
|
|
163
|
+
},
|
|
164
|
+
{ x: 0, y: 0 }
|
|
165
|
+
);
|
|
166
|
+
return { x: Math.round(sum.x / length), y: Math.round(sum.y / length) };
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function createInputCreator() {
|
|
170
|
+
let prevInput;
|
|
171
|
+
let currentInput;
|
|
172
|
+
let startInput;
|
|
173
|
+
let startMultiInput;
|
|
174
|
+
let id = 0;
|
|
175
|
+
return function(rawInput) {
|
|
176
|
+
prevInput = currentInput;
|
|
177
|
+
if (rawInput !== void 0) {
|
|
178
|
+
id = Number.MAX_SAFE_INTEGER > id ? ++id : 1;
|
|
179
|
+
const enriched = enrichInput(rawInput, id);
|
|
180
|
+
currentInput = enriched;
|
|
181
|
+
const { isStart, pointLength } = enriched;
|
|
182
|
+
if (isStart) {
|
|
183
|
+
startInput = enriched;
|
|
184
|
+
prevInput = void 0;
|
|
185
|
+
startMultiInput = pointLength > 1 ? enriched : void 0;
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
...enriched,
|
|
189
|
+
prevInput,
|
|
190
|
+
startMultiInput,
|
|
191
|
+
startInput
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function enrichInput(rawInput, id) {
|
|
197
|
+
const { phase, points, changedPoints, nativeEvent } = rawInput;
|
|
198
|
+
const pointLength = points.length;
|
|
199
|
+
const isStart = PHASE_START === phase;
|
|
200
|
+
const isEnd = phase === "end" && pointLength === 0 || phase === "cancel";
|
|
201
|
+
const timestamp = Date.now();
|
|
202
|
+
const center = getCenter(points) || getCenter(changedPoints);
|
|
203
|
+
const { currentTarget } = nativeEvent;
|
|
204
|
+
return Object.assign(rawInput, {
|
|
205
|
+
id,
|
|
206
|
+
x: center.x,
|
|
207
|
+
y: center.y,
|
|
208
|
+
timestamp,
|
|
209
|
+
isStart,
|
|
210
|
+
isEnd,
|
|
211
|
+
pointLength,
|
|
212
|
+
currentTarget,
|
|
213
|
+
getOffset(el = currentTarget) {
|
|
214
|
+
const rect = el.getBoundingClientRect();
|
|
215
|
+
return {
|
|
216
|
+
x: center.x - Math.round(rect.left),
|
|
217
|
+
y: center.y - Math.round(rect.top)
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
function createTouchInputCreator(el) {
|
|
223
|
+
const inputCreator = createInputCreator();
|
|
224
|
+
return function(event) {
|
|
225
|
+
const targets = [];
|
|
226
|
+
const points = [];
|
|
227
|
+
Array.from(event.touches).forEach(({ clientX, clientY, target }) => {
|
|
228
|
+
if (el?.contains(target)) {
|
|
229
|
+
targets.push(target);
|
|
230
|
+
points.push({ clientX, clientY, target });
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
const changedPoints = Array.from(event.changedTouches).map(({ clientX, clientY, target }) => ({
|
|
234
|
+
clientX,
|
|
235
|
+
clientY,
|
|
236
|
+
target
|
|
237
|
+
}));
|
|
238
|
+
return inputCreator({
|
|
239
|
+
phase: event.type.replace("touch", ""),
|
|
240
|
+
changedPoints,
|
|
241
|
+
points,
|
|
242
|
+
nativeEvent: event,
|
|
243
|
+
target: event.target,
|
|
244
|
+
targets
|
|
245
|
+
});
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function createMouseInputCreator() {
|
|
249
|
+
let prevPoint;
|
|
250
|
+
let isMouseDown = false;
|
|
251
|
+
let mouseTarget = null;
|
|
252
|
+
const inputCreator = createInputCreator();
|
|
253
|
+
return function(event) {
|
|
254
|
+
const { clientX, clientY, type, button, target } = event;
|
|
255
|
+
let phaseStr;
|
|
256
|
+
let points = [{ clientX, clientY, target }];
|
|
257
|
+
if (type === "mousedown" && button === 0) {
|
|
258
|
+
mouseTarget = target;
|
|
259
|
+
isMouseDown = true;
|
|
260
|
+
phaseStr = "start";
|
|
261
|
+
} else {
|
|
262
|
+
if (!isMouseDown) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (type === "mousemove") {
|
|
266
|
+
phaseStr = "move";
|
|
267
|
+
} else if (type === "mouseup") {
|
|
268
|
+
points = [];
|
|
269
|
+
phaseStr = "end";
|
|
270
|
+
isMouseDown = false;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
const changedPoints = prevPoint || [{ clientX, clientY, target }];
|
|
274
|
+
prevPoint = [{ clientX, clientY, target }];
|
|
275
|
+
if (phaseStr !== void 0) {
|
|
276
|
+
return inputCreator({
|
|
277
|
+
phase: phaseStr,
|
|
278
|
+
changedPoints,
|
|
279
|
+
points,
|
|
280
|
+
target: mouseTarget,
|
|
281
|
+
targets: [mouseTarget],
|
|
282
|
+
nativeEvent: event
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function dispatchDomEvent(type, el, computed, eventInit) {
|
|
288
|
+
const payload = {};
|
|
289
|
+
for (const key in computed) {
|
|
290
|
+
if (!["target", "currentTarget", "type"].includes(key)) {
|
|
291
|
+
payload[key] = computed[key];
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
let event;
|
|
295
|
+
if (document.createEvent) {
|
|
296
|
+
event = document.createEvent("HTMLEvents");
|
|
297
|
+
event.initEvent(type, eventInit?.bubbles, eventInit?.cancelable);
|
|
298
|
+
} else {
|
|
299
|
+
event = new Event(type, eventInit);
|
|
300
|
+
}
|
|
301
|
+
Object.assign(event, payload, {
|
|
302
|
+
match: () => computed.targets && computed.targets.length > 0 && computed.targets.every(
|
|
303
|
+
(t) => event.currentTarget.contains(t)
|
|
304
|
+
)
|
|
305
|
+
});
|
|
306
|
+
return el.dispatchEvent(event);
|
|
307
|
+
}
|
|
308
|
+
function shouldPreventDefault(e, options) {
|
|
309
|
+
const { preventDefault } = options;
|
|
310
|
+
if (typeof preventDefault === "function") {
|
|
311
|
+
return preventDefault(e);
|
|
312
|
+
}
|
|
313
|
+
return !!preventDefault;
|
|
314
|
+
}
|
|
315
|
+
class Core extends AnyEvent {
|
|
316
|
+
/** 版本 */
|
|
317
|
+
v = "2.1.3";
|
|
318
|
+
/** 当前绑定元素 */
|
|
319
|
+
el;
|
|
320
|
+
/** 当前插件上下文 */
|
|
321
|
+
c;
|
|
322
|
+
__options;
|
|
323
|
+
__inputCreatorMap;
|
|
324
|
+
__computeFunctionList = [];
|
|
325
|
+
__computeFunctionCreatorList = [];
|
|
326
|
+
__pluginContexts = [];
|
|
327
|
+
__isIgnoreMouse = false;
|
|
328
|
+
constructor(el, options) {
|
|
329
|
+
super();
|
|
330
|
+
this.el = el;
|
|
331
|
+
this.c = {};
|
|
332
|
+
this.__options = { ...DEFAULT_OPTIONS, ...options };
|
|
333
|
+
const touchInputCreator = createTouchInputCreator(this.el);
|
|
334
|
+
const mouseInputCreator = createMouseInputCreator();
|
|
335
|
+
this.__inputCreatorMap = {
|
|
336
|
+
touchstart: touchInputCreator,
|
|
337
|
+
touchmove: touchInputCreator,
|
|
338
|
+
touchend: touchInputCreator,
|
|
339
|
+
touchcancel: touchInputCreator,
|
|
340
|
+
mousedown: mouseInputCreator,
|
|
341
|
+
mousemove: mouseInputCreator,
|
|
342
|
+
mouseup: mouseInputCreator
|
|
343
|
+
};
|
|
344
|
+
this.on("at:after", (e) => {
|
|
345
|
+
const { target, __type } = e;
|
|
346
|
+
const { domEvents } = this.__options;
|
|
347
|
+
if (domEvents && this.el !== void 0 && target) {
|
|
348
|
+
dispatchDomEvent(__type, target, e, domEvents);
|
|
349
|
+
dispatchDomEvent("at:after", target, e, domEvents);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
if (el !== void 0) {
|
|
353
|
+
;
|
|
354
|
+
el.style.webkitTapHighlightColor = "rgba(0,0,0,0)";
|
|
355
|
+
let supportsPassive = false;
|
|
356
|
+
try {
|
|
357
|
+
const opts = {};
|
|
358
|
+
Object.defineProperty(opts, "passive", {
|
|
359
|
+
get() {
|
|
360
|
+
supportsPassive = true;
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
window.addEventListener("_", () => {
|
|
364
|
+
}, opts);
|
|
365
|
+
} catch {
|
|
366
|
+
}
|
|
367
|
+
this.on(
|
|
368
|
+
"u",
|
|
369
|
+
bindEvents(
|
|
370
|
+
el,
|
|
371
|
+
this.catchEvent.bind(this),
|
|
372
|
+
this.__options.preventDefault === false && supportsPassive ? { passive: true } : { passive: false }
|
|
373
|
+
)
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
/** 加载并初始化插件 */
|
|
378
|
+
use(plugin, pluginOptions) {
|
|
379
|
+
this.__pluginContexts.push(plugin(this, pluginOptions));
|
|
380
|
+
}
|
|
381
|
+
/** 监听input变化 */
|
|
382
|
+
catchEvent(event) {
|
|
383
|
+
const input = this.__inputCreatorMap[event.type](event);
|
|
384
|
+
if (input !== void 0) {
|
|
385
|
+
const stopPropagation = () => event.stopPropagation();
|
|
386
|
+
const stopImmediatePropagation = () => event.stopImmediatePropagation();
|
|
387
|
+
const preventDefault = () => event.preventDefault();
|
|
388
|
+
if (shouldPreventDefault(event, this.__options)) {
|
|
389
|
+
preventDefault();
|
|
390
|
+
} else if (event.type === "touchstart") {
|
|
391
|
+
this.__isIgnoreMouse = true;
|
|
392
|
+
} else if (event.type === "touchmove") {
|
|
393
|
+
this.__isIgnoreMouse = false;
|
|
394
|
+
}
|
|
395
|
+
if (this.__isIgnoreMouse && event.type.startsWith("mouse")) {
|
|
396
|
+
if (event.type === "mouseup") {
|
|
397
|
+
this.__isIgnoreMouse = false;
|
|
398
|
+
}
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
this.emit("input", input);
|
|
402
|
+
this.emit2(`at:${input.phase}`, input, {});
|
|
403
|
+
const computed = {};
|
|
404
|
+
this.__computeFunctionList.forEach((fn) => {
|
|
405
|
+
const result = fn(input, computed);
|
|
406
|
+
if (result !== void 0) {
|
|
407
|
+
for (const key in result) {
|
|
408
|
+
computed[key] = result[key];
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
this.emit("computed", {
|
|
413
|
+
...input,
|
|
414
|
+
...computed,
|
|
415
|
+
stopPropagation,
|
|
416
|
+
stopImmediatePropagation,
|
|
417
|
+
preventDefault
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
/** 缓存计算函数生成器到队列 */
|
|
422
|
+
compute(computeFunctionCreatorList, callback) {
|
|
423
|
+
for (const creator of computeFunctionCreatorList) {
|
|
424
|
+
if (!this.__computeFunctionCreatorList.includes(creator)) {
|
|
425
|
+
this.__computeFunctionCreatorList.push(creator);
|
|
426
|
+
this.__computeFunctionList.push(creator());
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
this.on("computed", callback);
|
|
430
|
+
}
|
|
431
|
+
/** 拦截器 */
|
|
432
|
+
beforeEach(interceptor) {
|
|
433
|
+
super.beforeEach((type, next) => {
|
|
434
|
+
if (this.c?.name) {
|
|
435
|
+
interceptor(type, next);
|
|
436
|
+
} else {
|
|
437
|
+
next();
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
/** 获取识别器通过名字 */
|
|
442
|
+
get(name) {
|
|
443
|
+
return this.__pluginContexts.find((ctx) => name === ctx.name);
|
|
444
|
+
}
|
|
445
|
+
/** 设置选项 */
|
|
446
|
+
set(newOptions) {
|
|
447
|
+
this.__options = { ...this.__options, ...newOptions };
|
|
448
|
+
}
|
|
449
|
+
/** 带DOM事件的emit */
|
|
450
|
+
emit2(type, payload, pluginContext) {
|
|
451
|
+
this.c = pluginContext;
|
|
452
|
+
this.emit(type, { ...payload, type }, () => {
|
|
453
|
+
this.emit(
|
|
454
|
+
"at:after",
|
|
455
|
+
{
|
|
456
|
+
...payload,
|
|
457
|
+
name: type,
|
|
458
|
+
__type: type
|
|
459
|
+
}
|
|
460
|
+
);
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
/** 销毁 */
|
|
464
|
+
destroy() {
|
|
465
|
+
this.emit("u");
|
|
466
|
+
super.destroy();
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
function bindEvents(el, handler, options) {
|
|
470
|
+
TOUCH_EVENTS.forEach((type) => {
|
|
471
|
+
el.addEventListener(type, handler, options);
|
|
472
|
+
});
|
|
473
|
+
MOUSE_EVENTS.forEach((type) => {
|
|
474
|
+
window.addEventListener(type, handler, options);
|
|
475
|
+
});
|
|
476
|
+
return () => {
|
|
477
|
+
TOUCH_EVENTS.forEach((type) => {
|
|
478
|
+
el.removeEventListener(type, handler);
|
|
479
|
+
});
|
|
480
|
+
MOUSE_EVENTS.forEach((type) => {
|
|
481
|
+
window.removeEventListener(type, handler);
|
|
482
|
+
});
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
function createComputeDeltaXY() {
|
|
486
|
+
return function(input) {
|
|
487
|
+
const { prevInput } = input;
|
|
488
|
+
let deltaX = 0;
|
|
489
|
+
let deltaY = 0;
|
|
490
|
+
let deltaXYAngle = 0;
|
|
491
|
+
if (prevInput !== void 0) {
|
|
492
|
+
deltaX = input.x - prevInput.x;
|
|
493
|
+
deltaY = input.y - prevInput.y;
|
|
494
|
+
if (deltaX !== 0 || deltaY !== 0) {
|
|
495
|
+
const distance = Math.sqrt(deltaX ** 2 + deltaY ** 2);
|
|
496
|
+
deltaXYAngle = Math.round(radToDeg(Math.acos(Math.abs(deltaX) / distance)));
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return { deltaX, deltaY, deltaXYAngle };
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
function createComputeDistance() {
|
|
503
|
+
let overallDirection;
|
|
504
|
+
let displacementX = 0;
|
|
505
|
+
let displacementY = 0;
|
|
506
|
+
let distanceX = 0;
|
|
507
|
+
let distanceY = 0;
|
|
508
|
+
let distance = 0;
|
|
509
|
+
return function(input) {
|
|
510
|
+
const { phase, startInput } = input;
|
|
511
|
+
if (phase === "start") {
|
|
512
|
+
displacementX = 0;
|
|
513
|
+
displacementY = 0;
|
|
514
|
+
distanceX = 0;
|
|
515
|
+
distanceY = 0;
|
|
516
|
+
distance = 0;
|
|
517
|
+
} else if (phase === "move") {
|
|
518
|
+
displacementX = Math.round(input.points[0].clientX - startInput.points[0].clientX);
|
|
519
|
+
displacementY = Math.round(input.points[0].clientY - startInput.points[0].clientY);
|
|
520
|
+
distanceX = Math.abs(displacementX);
|
|
521
|
+
distanceY = Math.abs(displacementY);
|
|
522
|
+
distance = Math.round(vectorLength({ x: distanceX, y: distanceY }));
|
|
523
|
+
overallDirection = computeDirection(displacementX, displacementY);
|
|
524
|
+
}
|
|
525
|
+
return {
|
|
526
|
+
displacementX,
|
|
527
|
+
displacementY,
|
|
528
|
+
distanceX,
|
|
529
|
+
distanceY,
|
|
530
|
+
distance,
|
|
531
|
+
overallDirection
|
|
532
|
+
};
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
function createComputeVelocity() {
|
|
536
|
+
let direction;
|
|
537
|
+
let lastRecordInput;
|
|
538
|
+
let velocityX = 0;
|
|
539
|
+
let velocityY = 0;
|
|
540
|
+
let speedX = 0;
|
|
541
|
+
let speedY = 0;
|
|
542
|
+
return function(input) {
|
|
543
|
+
if (input !== void 0) {
|
|
544
|
+
lastRecordInput ||= input.startInput;
|
|
545
|
+
const deltaTime = input.timestamp - lastRecordInput.timestamp;
|
|
546
|
+
if (deltaTime > 16) {
|
|
547
|
+
const deltaX = input.x - lastRecordInput.x;
|
|
548
|
+
const deltaY = input.y - lastRecordInput.y;
|
|
549
|
+
speedX = Math.round(deltaX / deltaTime * 100) / 100;
|
|
550
|
+
speedY = Math.round(deltaY / deltaTime * 100) / 100;
|
|
551
|
+
velocityX = Math.abs(speedX);
|
|
552
|
+
velocityY = Math.abs(speedY);
|
|
553
|
+
direction = computeDirection(deltaX, deltaY);
|
|
554
|
+
lastRecordInput = input;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return {
|
|
558
|
+
velocityX,
|
|
559
|
+
velocityY,
|
|
560
|
+
speedX,
|
|
561
|
+
speedY,
|
|
562
|
+
direction
|
|
563
|
+
};
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
function Pan(at, options) {
|
|
567
|
+
const context = createPluginContext(PAN_DEFAULT_OPTIONS, options);
|
|
568
|
+
at.compute(
|
|
569
|
+
[createComputeVelocity, createComputeDistance, createComputeDeltaXY],
|
|
570
|
+
(computed) => {
|
|
571
|
+
resetIfTerminalState(context);
|
|
572
|
+
if (abortIfDisabled(context)) {
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
const isRecognized = (function() {
|
|
576
|
+
const { pointLength, distance } = computed;
|
|
577
|
+
return context.pointLength === pointLength && context.threshold <= distance;
|
|
578
|
+
})();
|
|
579
|
+
context.state = computeFSM(isRecognized, context.state, computed.phase);
|
|
580
|
+
if (isRecognized || isEndOrCancelState(context.state)) {
|
|
581
|
+
const { name } = context;
|
|
582
|
+
at.emit2(name, computed, context);
|
|
583
|
+
at.emit2(name + stateToPhase(context.state), computed, context);
|
|
584
|
+
if (!["end", "cancel"].includes(computed.phase) && computed.direction) {
|
|
585
|
+
at.emit2(name + computed.direction, computed, context);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
);
|
|
590
|
+
return context;
|
|
591
|
+
}
|
|
592
|
+
export { Core, Pan };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pxd",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.64",
|
|
4
4
|
"description": "A Vue 2.7 & 3.2 universal component library. Built-in light/dark theme. PC & mobile ready. Animation-free mode supported.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"component-library",
|
|
@@ -96,8 +96,6 @@
|
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"dependencies": {
|
|
99
|
-
"@any-touch/core": "^2.2.0",
|
|
100
|
-
"@any-touch/pan": "^2.2.0",
|
|
101
99
|
"@chenglou/pretext": "^0.0.6",
|
|
102
100
|
"@floating-ui/dom": "^1.7.6",
|
|
103
101
|
"@gdsicon/vue": "^1.0.9",
|