@flowgram-vue/core 0.2.0

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.
Files changed (133) hide show
  1. package/LICENSE +22 -0
  2. package/dist/index.cjs +0 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +0 -0
  6. package/dist/index.js.map +1 -0
  7. package/package.json +63 -0
  8. package/src/common/config-entity.ts +80 -0
  9. package/src/common/entity-data.ts +171 -0
  10. package/src/common/entity-manager-contribution.ts +12 -0
  11. package/src/common/entity-manager.ts +475 -0
  12. package/src/common/entity.ts +482 -0
  13. package/src/common/index.ts +22 -0
  14. package/src/common/playground-context.ts +35 -0
  15. package/src/common/playground-decorator-helper.ts +113 -0
  16. package/src/common/playground-decorators.ts +85 -0
  17. package/src/common/playground-schedule.ts +30 -0
  18. package/src/common/protect-wheel-area.ts +11 -0
  19. package/src/common/schema/index.ts +14 -0
  20. package/src/common/schema/node.ts +15 -0
  21. package/src/common/schema/opacity-schema.ts +19 -0
  22. package/src/common/schema/origin-schema.ts +35 -0
  23. package/src/common/schema/position-schema.ts +35 -0
  24. package/src/common/schema/rotation-schema.ts +19 -0
  25. package/src/common/schema/scale-schema.ts +35 -0
  26. package/src/common/schema/size-schema.ts +42 -0
  27. package/src/common/schema/skew-schema.ts +35 -0
  28. package/src/common/schema/transform-schema.ts +613 -0
  29. package/src/common/utils/bounds.spec.ts +229 -0
  30. package/src/common/utils/bounds.ts +176 -0
  31. package/src/common/utils/index.ts +6 -0
  32. package/src/composables/index.ts +16 -0
  33. package/src/composables/use-config-entity.ts +31 -0
  34. package/src/composables/use-entities.ts +26 -0
  35. package/src/composables/use-entity-data-from-context.ts +34 -0
  36. package/src/composables/use-entity-from-context.ts +31 -0
  37. package/src/composables/use-listen-events.ts +22 -0
  38. package/src/composables/use-playground-container.ts +16 -0
  39. package/src/composables/use-playground-context.ts +15 -0
  40. package/src/composables/use-playground-drag.ts +31 -0
  41. package/src/composables/use-playground.ts +16 -0
  42. package/src/composables/use-refresh.ts +6 -0
  43. package/src/composables/use-service.ts +17 -0
  44. package/src/core/index.ts +8 -0
  45. package/src/core/layer/config/editor-state-config-entity.ts +180 -0
  46. package/src/core/layer/config/index.ts +7 -0
  47. package/src/core/layer/config/playground-config-entity.ts +604 -0
  48. package/src/core/layer/index.ts +8 -0
  49. package/src/core/layer/layer.ts +248 -0
  50. package/src/core/layer/playground-layer.ts +547 -0
  51. package/src/core/pipeline/index.ts +10 -0
  52. package/src/core/pipeline/pipeline-entities-selector.ts +200 -0
  53. package/src/core/pipeline/pipeline-entities.ts +230 -0
  54. package/src/core/pipeline/pipeline-registry.ts +344 -0
  55. package/src/core/pipeline/pipeline-renderer.ts +248 -0
  56. package/src/core/pipeline/pipeline-vue-utils.ts +96 -0
  57. package/src/core/pipeline/pipeline.ts +28 -0
  58. package/src/core/utils/index.ts +12 -0
  59. package/src/core/utils/inject-provider-decorators.ts +27 -0
  60. package/src/core/utils/lazy-inject-decorators.ts +38 -0
  61. package/src/core/utils/mouse-touch-event.ts +120 -0
  62. package/src/core/utils/playground-drag.ts +511 -0
  63. package/src/core/utils/playground-gesture.spec.ts +135 -0
  64. package/src/core/utils/playground-gesture.ts +118 -0
  65. package/src/core/utils/tween.ts +156 -0
  66. package/src/core/utils/use-gesture/core/Controller.ts +212 -0
  67. package/src/core/utils/use-gesture/core/EventStore.ts +46 -0
  68. package/src/core/utils/use-gesture/core/TimeoutStore.ts +28 -0
  69. package/src/core/utils/use-gesture/core/actions.ts +63 -0
  70. package/src/core/utils/use-gesture/core/config/commonConfigResolver.ts +86 -0
  71. package/src/core/utils/use-gesture/core/config/coordinatesConfigResolver.ts +48 -0
  72. package/src/core/utils/use-gesture/core/config/dragConfigResolver.ts +140 -0
  73. package/src/core/utils/use-gesture/core/config/hoverConfigResolver.ts +11 -0
  74. package/src/core/utils/use-gesture/core/config/moveConfigResolver.ts +11 -0
  75. package/src/core/utils/use-gesture/core/config/pinchConfigResolver.ts +59 -0
  76. package/src/core/utils/use-gesture/core/config/resolver.ts +70 -0
  77. package/src/core/utils/use-gesture/core/config/scrollConfigResolver.ts +8 -0
  78. package/src/core/utils/use-gesture/core/config/sharedConfigResolver.ts +28 -0
  79. package/src/core/utils/use-gesture/core/config/support.ts +52 -0
  80. package/src/core/utils/use-gesture/core/config/wheelConfigResolver.ts +8 -0
  81. package/src/core/utils/use-gesture/core/engines/CoordinatesEngine.ts +78 -0
  82. package/src/core/utils/use-gesture/core/engines/DragEngine.ts +403 -0
  83. package/src/core/utils/use-gesture/core/engines/Engine.ts +406 -0
  84. package/src/core/utils/use-gesture/core/engines/HoverEngine.ts +43 -0
  85. package/src/core/utils/use-gesture/core/engines/MoveEngine.ts +52 -0
  86. package/src/core/utils/use-gesture/core/engines/PinchEngine.ts +345 -0
  87. package/src/core/utils/use-gesture/core/engines/ScrollEngine.ts +42 -0
  88. package/src/core/utils/use-gesture/core/engines/WheelEngine.ts +48 -0
  89. package/src/core/utils/use-gesture/core/index.ts +7 -0
  90. package/src/core/utils/use-gesture/core/parser.ts +92 -0
  91. package/src/core/utils/use-gesture/core/types/action.ts +19 -0
  92. package/src/core/utils/use-gesture/core/types/config.ts +255 -0
  93. package/src/core/utils/use-gesture/core/types/handlers.ts +73 -0
  94. package/src/core/utils/use-gesture/core/types/index.ts +11 -0
  95. package/src/core/utils/use-gesture/core/types/internalConfig.ts +80 -0
  96. package/src/core/utils/use-gesture/core/types/state.ts +275 -0
  97. package/src/core/utils/use-gesture/core/types/utils.ts +204 -0
  98. package/src/core/utils/use-gesture/core/types.ts +8 -0
  99. package/src/core/utils/use-gesture/core/utils/events.ts +158 -0
  100. package/src/core/utils/use-gesture/core/utils/fn.ts +32 -0
  101. package/src/core/utils/use-gesture/core/utils/maths.ts +63 -0
  102. package/src/core/utils/use-gesture/core/utils/state.ts +24 -0
  103. package/src/core/utils/use-gesture/core/utils.ts +8 -0
  104. package/src/core/utils/use-gesture/index.ts +6 -0
  105. package/src/core/utils/use-gesture/vanilla/DragGesture.ts +27 -0
  106. package/src/core/utils/use-gesture/vanilla/Gesture.ts +45 -0
  107. package/src/core/utils/use-gesture/vanilla/HoverGesture.ts +27 -0
  108. package/src/core/utils/use-gesture/vanilla/MoveGesture.ts +27 -0
  109. package/src/core/utils/use-gesture/vanilla/PinchGesture.ts +27 -0
  110. package/src/core/utils/use-gesture/vanilla/Recognizer.ts +43 -0
  111. package/src/core/utils/use-gesture/vanilla/ScrollGesture.ts +27 -0
  112. package/src/core/utils/use-gesture/vanilla/WheelGesture.ts +27 -0
  113. package/src/core/utils/use-gesture/vanilla/createGesture.ts +18 -0
  114. package/src/core/utils/use-gesture/vanilla/index.ts +18 -0
  115. package/src/env.d.ts +10 -0
  116. package/src/index.ts +17 -0
  117. package/src/playground-config.ts +70 -0
  118. package/src/playground-container.ts +129 -0
  119. package/src/playground-contribution.ts +81 -0
  120. package/src/playground-mock-tools.ts +143 -0
  121. package/src/playground.ts +401 -0
  122. package/src/plugin/index.ts +6 -0
  123. package/src/plugin/plugin.ts +226 -0
  124. package/src/services/clipboard-service.ts +40 -0
  125. package/src/services/context-menu-service.ts +25 -0
  126. package/src/services/index.ts +10 -0
  127. package/src/services/logger-service.ts +49 -0
  128. package/src/services/selection-service.ts +54 -0
  129. package/src/services/storage-service.ts +65 -0
  130. package/src/vue/index.ts +8 -0
  131. package/src/vue/playground-vue-context.ts +22 -0
  132. package/src/vue/playground-vue-provider.ts +115 -0
  133. package/src/vue/playground-vue-renderer.vue +44 -0
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export type Vector2 = [number, number];
7
+ export type WebKitGestureEvent = PointerEvent & { scale: number; rotation: number };
8
+ export type Target = EventTarget | { current: EventTarget | null };
9
+ export type PointerType = 'mouse' | 'touch' | 'pen';
10
+
11
+ // replaces NonUndefined from 4.7 and inferior versions
12
+ export type NonUndefined<T> = T extends undefined ? never : T;
13
+ export type EventHandler<E extends Event = Event> = (event: E) => void;
14
+
15
+ // rip off from React types
16
+ export interface DOMHandlers {
17
+ // Clipboard Events
18
+ onCopy?: EventHandler<ClipboardEvent>;
19
+ onCopyCapture?: EventHandler<ClipboardEvent>;
20
+ onCut?: EventHandler<ClipboardEvent>;
21
+ onCutCapture?: EventHandler<ClipboardEvent>;
22
+ onPaste?: EventHandler<ClipboardEvent>;
23
+ onPasteCapture?: EventHandler<ClipboardEvent>;
24
+
25
+ // Composition Events
26
+ onCompositionEnd?: EventHandler<CompositionEvent>;
27
+ onCompositionEndCapture?: EventHandler<CompositionEvent>;
28
+ onCompositionStart?: EventHandler<CompositionEvent>;
29
+ onCompositionStartCapture?: EventHandler<CompositionEvent>;
30
+ onCompositionUpdate?: EventHandler<CompositionEvent>;
31
+ onCompositionUpdateCapture?: EventHandler<CompositionEvent>;
32
+
33
+ // Focus Events
34
+ onFocus?: EventHandler<FocusEvent>;
35
+ onFocusCapture?: EventHandler<FocusEvent>;
36
+ onBlur?: EventHandler<FocusEvent>;
37
+ onBlurCapture?: EventHandler<FocusEvent>;
38
+
39
+ // Form Events
40
+ onChange?: EventHandler<FormDataEvent>;
41
+ onChangeCapture?: EventHandler<FormDataEvent>;
42
+ onBeforeInput?: EventHandler<FormDataEvent>;
43
+ onBeforeInputCapture?: EventHandler<FormDataEvent>;
44
+ onInput?: EventHandler<FormDataEvent>;
45
+ onInputCapture?: EventHandler<FormDataEvent>;
46
+ onReset?: EventHandler<FormDataEvent>;
47
+ onResetCapture?: EventHandler<FormDataEvent>;
48
+ onSubmit?: EventHandler<FormDataEvent>;
49
+ onSubmitCapture?: EventHandler<FormDataEvent>;
50
+ onInvalid?: EventHandler<FormDataEvent>;
51
+ onInvalidCapture?: EventHandler<FormDataEvent>;
52
+
53
+ // Image Events
54
+ onLoad?: EventHandler;
55
+ onLoadCapture?: EventHandler;
56
+ onError?: EventHandler; // also a Media Event
57
+ onErrorCapture?: EventHandler; // also a Media Event
58
+
59
+ // Keyboard Events
60
+ onKeyDown?: EventHandler<KeyboardEvent>;
61
+ onKeyDownCapture?: EventHandler<KeyboardEvent>;
62
+ onKeyUp?: EventHandler<KeyboardEvent>;
63
+ onKeyUpCapture?: EventHandler<KeyboardEvent>;
64
+
65
+ // Media Events
66
+ onAbort?: EventHandler;
67
+ onAbortCapture?: EventHandler;
68
+ onCanPlay?: EventHandler;
69
+ onCanPlayCapture?: EventHandler;
70
+ onCanPlayThrough?: EventHandler;
71
+ onCanPlayThroughCapture?: EventHandler;
72
+ onDurationChange?: EventHandler;
73
+ onDurationChangeCapture?: EventHandler;
74
+ onEmptied?: EventHandler;
75
+ onEmptiedCapture?: EventHandler;
76
+ onEncrypted?: EventHandler;
77
+ onEncryptedCapture?: EventHandler;
78
+ onEnded?: EventHandler;
79
+ onEndedCapture?: EventHandler;
80
+ onLoadedData?: EventHandler;
81
+ onLoadedDataCapture?: EventHandler;
82
+ onLoadedMetadata?: EventHandler;
83
+ onLoadedMetadataCapture?: EventHandler;
84
+ onLoadStart?: EventHandler;
85
+ onLoadStartCapture?: EventHandler;
86
+ onPause?: EventHandler;
87
+ onPauseCapture?: EventHandler;
88
+ onPlay?: EventHandler;
89
+ onPlayCapture?: EventHandler;
90
+ onPlaying?: EventHandler;
91
+ onPlayingCapture?: EventHandler;
92
+ onProgress?: EventHandler;
93
+ onProgressCapture?: EventHandler;
94
+ onRateChange?: EventHandler;
95
+ onRateChangeCapture?: EventHandler;
96
+ onSeeked?: EventHandler;
97
+ onSeekedCapture?: EventHandler;
98
+ onSeeking?: EventHandler;
99
+ onSeekingCapture?: EventHandler;
100
+ onStalled?: EventHandler;
101
+ onStalledCapture?: EventHandler;
102
+ onSuspend?: EventHandler;
103
+ onSuspendCapture?: EventHandler;
104
+ onTimeUpdate?: EventHandler;
105
+ onTimeUpdateCapture?: EventHandler;
106
+ onVolumeChange?: EventHandler;
107
+ onVolumeChangeCapture?: EventHandler;
108
+ onWaiting?: EventHandler;
109
+ onWaitingCapture?: EventHandler;
110
+
111
+ // MouseEvents
112
+ onAuxClick?: EventHandler<MouseEvent>;
113
+ onAuxClickCapture?: EventHandler<MouseEvent>;
114
+ onClick?: EventHandler<MouseEvent>;
115
+ onClickCapture?: EventHandler<MouseEvent>;
116
+ onContextMenu?: EventHandler<MouseEvent>;
117
+ onContextMenuCapture?: EventHandler<MouseEvent>;
118
+ onDoubleClick?: EventHandler<MouseEvent>;
119
+ onDoubleClickCapture?: EventHandler<MouseEvent>;
120
+ onDrag?: EventHandler<DragEvent>;
121
+ onDragCapture?: EventHandler<DragEvent>;
122
+ onDragEnd?: EventHandler<DragEvent>;
123
+ onDragEndCapture?: EventHandler<DragEvent>;
124
+ onDragEnter?: EventHandler<DragEvent>;
125
+ onDragEnterCapture?: EventHandler<DragEvent>;
126
+ onDragExit?: EventHandler<DragEvent>;
127
+ onDragExitCapture?: EventHandler<DragEvent>;
128
+ onDragLeave?: EventHandler<DragEvent>;
129
+ onDragLeaveCapture?: EventHandler<DragEvent>;
130
+ onDragOver?: EventHandler<DragEvent>;
131
+ onDragOverCapture?: EventHandler<DragEvent>;
132
+ onDragStart?: EventHandler<DragEvent>;
133
+ onDragStartCapture?: EventHandler<DragEvent>;
134
+ onDrop?: EventHandler<DragEvent>;
135
+ onDropCapture?: EventHandler<DragEvent>;
136
+ onMouseDown?: EventHandler<MouseEvent>;
137
+ onMouseDownCapture?: EventHandler<MouseEvent>;
138
+ onMouseEnter?: EventHandler<MouseEvent>;
139
+ onMouseLeave?: EventHandler<MouseEvent>;
140
+ onMouseMove?: EventHandler<MouseEvent>;
141
+ onMouseMoveCapture?: EventHandler<MouseEvent>;
142
+ onMouseOut?: EventHandler<MouseEvent>;
143
+ onMouseOutCapture?: EventHandler<MouseEvent>;
144
+ onMouseOver?: EventHandler<MouseEvent>;
145
+ onMouseOverCapture?: EventHandler<MouseEvent>;
146
+ onMouseUp?: EventHandler<MouseEvent>;
147
+ onMouseUpCapture?: EventHandler<MouseEvent>;
148
+
149
+ // Selection Events
150
+ onSelect?: EventHandler;
151
+ onSelectCapture?: EventHandler;
152
+
153
+ // Touch Events
154
+ onTouchCancel?: EventHandler<TouchEvent>;
155
+ onTouchCancelCapture?: EventHandler<TouchEvent>;
156
+ onTouchEnd?: EventHandler<TouchEvent>;
157
+ onTouchEndCapture?: EventHandler<TouchEvent>;
158
+ onTouchMove?: EventHandler<TouchEvent>;
159
+ onTouchMoveCapture?: EventHandler<TouchEvent>;
160
+ onTouchStart?: EventHandler<TouchEvent>;
161
+ onTouchStartCapture?: EventHandler<TouchEvent>;
162
+
163
+ // Pointer Events
164
+ onPointerDown?: EventHandler<PointerEvent>;
165
+ onPointerDownCapture?: EventHandler<PointerEvent>;
166
+ onPointerMove?: EventHandler<PointerEvent>;
167
+ onPointerMoveCapture?: EventHandler<PointerEvent>;
168
+ onPointerUp?: EventHandler<PointerEvent>;
169
+ onPointerUpCapture?: EventHandler<PointerEvent>;
170
+ onPointerCancel?: EventHandler<PointerEvent>;
171
+ onPointerCancelCapture?: EventHandler<PointerEvent>;
172
+ onPointerEnter?: EventHandler<PointerEvent>;
173
+ onPointerEnterCapture?: EventHandler<PointerEvent>;
174
+ onPointerLeave?: EventHandler<PointerEvent>;
175
+ onPointerLeaveCapture?: EventHandler<PointerEvent>;
176
+ onPointerOver?: EventHandler<PointerEvent>;
177
+ onPointerOverCapture?: EventHandler<PointerEvent>;
178
+ onPointerOut?: EventHandler<PointerEvent>;
179
+ onPointerOutCapture?: EventHandler<PointerEvent>;
180
+ onGotPointerCapture?: EventHandler<PointerEvent>;
181
+ onGotPointerCaptureCapture?: EventHandler<PointerEvent>;
182
+ onLostPointerCapture?: EventHandler<PointerEvent>;
183
+ onLostPointerCaptureCapture?: EventHandler<PointerEvent>;
184
+
185
+ // UI Events
186
+ onScroll?: EventHandler<UIEvent>;
187
+ onScrollCapture?: EventHandler<UIEvent>;
188
+
189
+ // Wheel Events
190
+ onWheel?: EventHandler<WheelEvent>;
191
+ onWheelCapture?: EventHandler<WheelEvent>;
192
+
193
+ // Animation Events
194
+ onAnimationStart?: EventHandler<AnimationEvent>;
195
+ onAnimationStartCapture?: EventHandler<AnimationEvent>;
196
+ onAnimationEnd?: EventHandler<AnimationEvent>;
197
+ onAnimationEndCapture?: EventHandler<AnimationEvent>;
198
+ onAnimationIteration?: EventHandler<AnimationEvent>;
199
+ onAnimationIterationCapture?: EventHandler<AnimationEvent>;
200
+
201
+ // Transition Events
202
+ onTransitionEnd?: EventHandler<TransitionEvent>;
203
+ onTransitionEndCapture?: EventHandler<TransitionEvent>;
204
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ // type exports for core
7
+
8
+ export * from './types/index';
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { PointerType } from '../types';
7
+ import { Vector2 } from '../types';
8
+
9
+ const EVENT_TYPE_MAP: any = {
10
+ pointer: { start: 'down', change: 'move', end: 'up' },
11
+ mouse: { start: 'down', change: 'move', end: 'up' },
12
+ touch: { start: 'start', change: 'move', end: 'end' },
13
+ gesture: { start: 'start', change: 'change', end: 'end' },
14
+ };
15
+
16
+ function capitalize(string: string) {
17
+ if (!string) return '';
18
+ return string[0].toUpperCase() + string.slice(1);
19
+ }
20
+
21
+ const actionsWithoutCaptureSupported = ['enter', 'leave'];
22
+
23
+ function hasCapture(capture = false, actionKey: string) {
24
+ return capture && !actionsWithoutCaptureSupported.includes(actionKey);
25
+ }
26
+
27
+ export function toHandlerProp(device: string, action = '', capture: boolean = false) {
28
+ const deviceProps = EVENT_TYPE_MAP[device];
29
+ const actionKey = deviceProps ? deviceProps[action] || action : action;
30
+ return (
31
+ 'on' +
32
+ capitalize(device) +
33
+ capitalize(actionKey) +
34
+ (hasCapture(capture, actionKey) ? 'Capture' : '')
35
+ );
36
+ }
37
+
38
+ const pointerCaptureEvents = ['gotpointercapture', 'lostpointercapture'];
39
+
40
+ export function parseProp(prop: string) {
41
+ let eventKey = prop.substring(2).toLowerCase();
42
+ const passive = !!~eventKey.indexOf('passive');
43
+ if (passive) eventKey = eventKey.replace('passive', '');
44
+
45
+ const captureKey = pointerCaptureEvents.includes(eventKey) ? 'capturecapture' : 'capture';
46
+ // capture = true
47
+ const capture = !!~eventKey.indexOf(captureKey);
48
+ // pointermovecapture => pointermove
49
+ if (capture) eventKey = eventKey.replace('capture', '');
50
+ return { device: eventKey, capture, passive };
51
+ }
52
+
53
+ export function toDomEventType(device: string, action = '') {
54
+ const deviceProps = EVENT_TYPE_MAP[device];
55
+ const actionKey = deviceProps ? deviceProps[action] || action : action;
56
+ return device + actionKey;
57
+ }
58
+
59
+ export function isTouch(event: UIEvent) {
60
+ return 'touches' in event;
61
+ }
62
+
63
+ export function getPointerType(event: UIEvent): PointerType {
64
+ if (isTouch(event)) return 'touch';
65
+ if ('pointerType' in event) return (event as PointerEvent).pointerType as PointerType;
66
+ return 'mouse';
67
+ }
68
+
69
+ function getCurrentTargetTouchList(event: TouchEvent) {
70
+ return Array.from(event.touches).filter(
71
+ e =>
72
+ e.target === event.currentTarget ||
73
+ (event.currentTarget as Node)?.contains?.(e.target as Node),
74
+ );
75
+ }
76
+
77
+ function getTouchList(event: TouchEvent) {
78
+ return event.type === 'touchend' || event.type === 'touchcancel'
79
+ ? event.changedTouches
80
+ : event.targetTouches;
81
+ }
82
+
83
+ function getValueEvent<EventType extends TouchEvent | PointerEvent>(
84
+ event: EventType,
85
+ ): EventType extends TouchEvent ? Touch : PointerEvent {
86
+ return (isTouch(event) ? getTouchList(event as TouchEvent)[0] : event) as any;
87
+ }
88
+
89
+ export function distanceAngle(P1: Touch | PointerEvent, P2: Touch | PointerEvent) {
90
+ // add a try catch
91
+ // attempt to fix https://github.com/pmndrs/use-gesture/issues/551
92
+ try {
93
+ const dx = P2.clientX - P1.clientX;
94
+ const dy = P2.clientY - P1.clientY;
95
+ const cx = (P2.clientX + P1.clientX) / 2;
96
+ const cy = (P2.clientY + P1.clientY) / 2;
97
+
98
+ const distance = Math.hypot(dx, dy);
99
+ const angle = -(Math.atan2(dx, dy) * 180) / Math.PI;
100
+ const origin = [cx, cy] as Vector2;
101
+ return { angle, distance, origin };
102
+ } catch {}
103
+ return null;
104
+ }
105
+
106
+ export function touchIds(event: TouchEvent) {
107
+ return getCurrentTargetTouchList(event).map(touch => touch.identifier);
108
+ }
109
+
110
+ export function touchDistanceAngle(event: TouchEvent, ids: number[]) {
111
+ const [P1, P2] = Array.from(event.touches).filter(touch => ids.includes(touch.identifier));
112
+ return distanceAngle(P1, P2);
113
+ }
114
+
115
+ export function pointerId(event: PointerEvent | TouchEvent) {
116
+ const valueEvent = getValueEvent(event);
117
+ return isTouch(event) ? (valueEvent as Touch).identifier : (valueEvent as PointerEvent).pointerId;
118
+ }
119
+
120
+ export function pointerValues(event: PointerEvent | TouchEvent): Vector2 {
121
+ // if ('spaceX' in event) return [event.spaceX, event.spaceY]
122
+ const valueEvent = getValueEvent(event);
123
+ return [valueEvent.clientX, valueEvent.clientY];
124
+ }
125
+
126
+ // wheel delta defaults from https://github.com/facebookarchive/fixed-data-table/blob/master/src/vendor_upstream/dom/normalizeWheel.js
127
+ const LINE_HEIGHT = 40;
128
+ const PAGE_HEIGHT = 800;
129
+
130
+ export function wheelValues(event: WheelEvent): Vector2 {
131
+ let { deltaX, deltaY, deltaMode } = event;
132
+ // normalize wheel values, especially for Firefox
133
+ if (deltaMode === 1) {
134
+ deltaX *= LINE_HEIGHT;
135
+ deltaY *= LINE_HEIGHT;
136
+ } else if (deltaMode === 2) {
137
+ deltaX *= PAGE_HEIGHT;
138
+ deltaY *= PAGE_HEIGHT;
139
+ }
140
+ return [deltaX, deltaY];
141
+ }
142
+
143
+ export function scrollValues(event: UIEvent): Vector2 {
144
+ // If the currentTarget is the window then we return the scrollX/Y position.
145
+ // If not (ie the currentTarget is a DOM element), then we return scrollLeft/Top
146
+ const { scrollX, scrollY, scrollLeft, scrollTop } = event.currentTarget as Element & Window;
147
+ return [scrollX ?? scrollLeft ?? 0, scrollY ?? scrollTop ?? 0];
148
+ }
149
+
150
+ export function getEventDetails(event: any) {
151
+ const payload: any = {};
152
+ if ('buttons' in event) payload.buttons = event.buttons;
153
+ if ('shiftKey' in event) {
154
+ const { shiftKey, altKey, metaKey, ctrlKey } = event;
155
+ Object.assign(payload, { shiftKey, altKey, metaKey, ctrlKey });
156
+ }
157
+ return payload;
158
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export function call<T>(v: T | ((...args: any[]) => T), ...args: any[]): T {
7
+ if (typeof v === 'function') {
8
+ // @ts-ignore
9
+ return v(...args);
10
+ } else {
11
+ return v;
12
+ }
13
+ }
14
+
15
+ export function noop() {}
16
+
17
+ export function chain(...fns: Function[]): Function {
18
+ if (fns.length === 0) return noop;
19
+ if (fns.length === 1) return fns[0];
20
+
21
+ return function (this: any) {
22
+ let result;
23
+ for (const fn of fns) {
24
+ result = fn.apply(this, arguments) || result;
25
+ }
26
+ return result;
27
+ };
28
+ }
29
+
30
+ export function assignDefault<T extends Object>(value: Partial<T> | undefined, fallback: T): T {
31
+ return Object.assign({}, fallback, value || {});
32
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { Vector2 } from '../types';
7
+
8
+ export function clamp(v: number, min: number, max: number) {
9
+ return Math.max(min, Math.min(v, max));
10
+ }
11
+
12
+ export const V = {
13
+ toVector<T>(v: T | [T, T] | undefined, fallback?: T | [T, T]): [T, T] {
14
+ if (v === undefined) v = fallback as T | [T, T];
15
+ return Array.isArray(v) ? v : [v, v];
16
+ },
17
+ add(v1: Vector2, v2: Vector2): Vector2 {
18
+ return [v1[0] + v2[0], v1[1] + v2[1]];
19
+ },
20
+ sub(v1: Vector2, v2: Vector2): Vector2 {
21
+ return [v1[0] - v2[0], v1[1] - v2[1]];
22
+ },
23
+ addTo(v1: Vector2, v2: Vector2) {
24
+ v1[0] += v2[0];
25
+ v1[1] += v2[1];
26
+ },
27
+ subTo(v1: Vector2, v2: Vector2) {
28
+ v1[0] -= v2[0];
29
+ v1[1] -= v2[1];
30
+ },
31
+ };
32
+
33
+ // Based on @aholachek ;)
34
+ // https://twitter.com/chpwn/status/285540192096497664
35
+ // iOS constant = 0.55
36
+
37
+ // https://medium.com/@nathangitter/building-fluid-interfaces-ios-swift-9732bb934bf5
38
+
39
+ function rubberband(distance: number, dimension: number, constant: number) {
40
+ if (dimension === 0 || Math.abs(dimension) === Infinity) return Math.pow(distance, constant * 5);
41
+ return (distance * dimension * constant) / (dimension + constant * distance);
42
+ }
43
+
44
+ export function rubberbandIfOutOfBounds(
45
+ position: number,
46
+ min: number,
47
+ max: number,
48
+ constant = 0.15,
49
+ ) {
50
+ if (constant === 0) return clamp(position, min, max);
51
+ if (position < min) return -rubberband(min - position, max - min, constant) + min;
52
+ if (position > max) return +rubberband(position - max, max - min, constant) + max;
53
+ return position;
54
+ }
55
+
56
+ export function computeRubberband(
57
+ bounds: [Vector2, Vector2],
58
+ [Vx, Vy]: Vector2,
59
+ [Rx, Ry]: Vector2,
60
+ ): Vector2 {
61
+ const [[X0, X1], [Y0, Y1]] = bounds;
62
+ return [rubberbandIfOutOfBounds(Vx, X0, X1, Rx), rubberbandIfOutOfBounds(Vy, Y0, Y1, Ry)];
63
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { CommonGestureState } from '../types';
7
+
8
+ // _movement rolls back to when it passed the bounds.
9
+ /**
10
+ * @note code is currently used in WheelEngine and PinchEngine.
11
+ */
12
+ export function clampStateInternalMovementToBounds(state: CommonGestureState) {
13
+ const [ox, oy] = state.overflow;
14
+ const [dx, dy] = state._delta;
15
+ const [dirx, diry] = state._direction;
16
+
17
+ if ((ox < 0 && dx > 0 && dirx < 0) || (ox > 0 && dx < 0 && dirx > 0)) {
18
+ state._movement[0] = state._movementBound[0] as number;
19
+ }
20
+
21
+ if ((oy < 0 && dy > 0 && diry < 0) || (oy > 0 && dy < 0 && diry > 0)) {
22
+ state._movement[1] = state._movementBound[1] as number;
23
+ }
24
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ // additional core exports
7
+
8
+ export { rubberbandIfOutOfBounds } from './utils/maths';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export * from './vanilla';
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { EventTypes, Handler, UserDragConfig } from '../core/types';
7
+ import { registerAction, dragAction } from '../core/actions';
8
+ import { Recognizer } from './Recognizer';
9
+
10
+ interface DragGestureConstructor {
11
+ new <EventType = EventTypes['drag']>(
12
+ target: EventTarget,
13
+ handler: Handler<'drag', EventType>,
14
+ config?: UserDragConfig,
15
+ ): DragGesture;
16
+ }
17
+
18
+ export interface DragGesture extends Recognizer<'drag'> {}
19
+
20
+ export const DragGesture: DragGestureConstructor = function <EventType = EventTypes['drag']>(
21
+ target: EventTarget,
22
+ handler: Handler<'drag', EventType>,
23
+ config?: UserDragConfig,
24
+ ) {
25
+ registerAction(dragAction);
26
+ return new Recognizer(target, { drag: handler }, config || {}, 'drag');
27
+ } as any;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import {
7
+ AnyHandlerEventTypes,
8
+ EventTypes,
9
+ GestureHandlers,
10
+ UserGestureConfig,
11
+ } from '../core/types';
12
+ import {
13
+ dragAction,
14
+ pinchAction,
15
+ scrollAction,
16
+ wheelAction,
17
+ moveAction,
18
+ hoverAction,
19
+ } from '../core/actions';
20
+ import { Recognizer } from './Recognizer';
21
+ import { createGesture } from './createGesture';
22
+
23
+ interface GestureConstructor {
24
+ new <HandlerTypes extends AnyHandlerEventTypes = EventTypes>(
25
+ target: EventTarget,
26
+ handlers: GestureHandlers<HandlerTypes>,
27
+ config?: UserGestureConfig,
28
+ ): Gesture;
29
+ }
30
+
31
+ export interface Gesture extends Recognizer {}
32
+
33
+ export const Gesture: GestureConstructor = function <
34
+ HandlerTypes extends AnyHandlerEventTypes = EventTypes,
35
+ >(target: EventTarget, handlers: GestureHandlers<HandlerTypes>, config?: UserGestureConfig) {
36
+ const gestureFunction = createGesture([
37
+ dragAction,
38
+ pinchAction,
39
+ scrollAction,
40
+ wheelAction,
41
+ moveAction,
42
+ hoverAction,
43
+ ]);
44
+ return gestureFunction(target, handlers, config || ({} as UserGestureConfig));
45
+ } as any;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { EventTypes, UserHoverConfig, Handler } from '../core/types';
7
+ import { registerAction, hoverAction } from '../core/actions';
8
+ import { Recognizer } from './Recognizer';
9
+
10
+ interface HoverGestureConstructor {
11
+ new <EventType = EventTypes['hover']>(
12
+ target: EventTarget,
13
+ handler: Handler<'hover', EventType>,
14
+ config?: UserHoverConfig,
15
+ ): HoverGesture;
16
+ }
17
+
18
+ export interface HoverGesture extends Recognizer<'hover'> {}
19
+
20
+ export const HoverGesture: HoverGestureConstructor = function <EventType = EventTypes['hover']>(
21
+ target: EventTarget,
22
+ handler: Handler<'hover', EventType>,
23
+ config?: UserHoverConfig,
24
+ ) {
25
+ registerAction(hoverAction);
26
+ return new Recognizer(target, { hover: handler }, config || {}, 'hover');
27
+ } as any;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { UserMoveConfig, Handler, EventTypes } from '../core/types';
7
+ import { registerAction, moveAction } from '../core/actions';
8
+ import { Recognizer } from './Recognizer';
9
+
10
+ interface MoveGestureConstructor {
11
+ new <EventType = EventTypes['move']>(
12
+ target: EventTarget,
13
+ handler: Handler<'move', EventType>,
14
+ config?: UserMoveConfig,
15
+ ): MoveGesture;
16
+ }
17
+
18
+ export interface MoveGesture extends Recognizer<'move'> {}
19
+
20
+ export const MoveGesture: MoveGestureConstructor = function <EventType = EventTypes['move']>(
21
+ target: EventTarget,
22
+ handler: Handler<'move', EventType>,
23
+ config?: UserMoveConfig,
24
+ ) {
25
+ registerAction(moveAction);
26
+ return new Recognizer(target, { move: handler }, config || {}, 'move');
27
+ } as any;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { UserPinchConfig, Handler, EventTypes } from '../core/types';
7
+ import { registerAction, pinchAction } from '../core/actions';
8
+ import { Recognizer } from './Recognizer';
9
+
10
+ interface PinchGestureConstructor {
11
+ new <EventType = EventTypes['pinch']>(
12
+ target: EventTarget,
13
+ handler: Handler<'pinch', EventType>,
14
+ config?: UserPinchConfig,
15
+ ): PinchGesture;
16
+ }
17
+
18
+ export interface PinchGesture extends Recognizer<'pinch'> {}
19
+
20
+ export const PinchGesture: PinchGestureConstructor = function <EventType = EventTypes['pinch']>(
21
+ target: EventTarget,
22
+ handler: Handler<'pinch', EventType>,
23
+ config?: UserPinchConfig,
24
+ ) {
25
+ registerAction(pinchAction);
26
+ return new Recognizer(target, { pinch: handler }, config || {}, 'pinch');
27
+ } as any;