@studiometa/js-toolkit 3.0.0-alpha.9 → 3.0.0-beta.1
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/Base/Base.js +2 -2
- package/Base/Base.js.map +2 -2
- package/Base/features.d.ts +1 -0
- package/Base/features.js +1 -0
- package/Base/features.js.map +2 -2
- package/Base/managers/EventsManager.js +2 -4
- package/Base/managers/EventsManager.js.map +2 -2
- package/Base/managers/OptionsManager.d.ts +2 -2
- package/Base/managers/OptionsManager.js +8 -8
- package/Base/managers/OptionsManager.js.map +2 -2
- package/Base/managers/RefsManager.js.map +2 -2
- package/Base/utils.d.ts +4 -0
- package/Base/utils.js +7 -3
- package/Base/utils.js.map +2 -2
- package/decorators/withBreakpointObserver.js +14 -9
- package/decorators/withBreakpointObserver.js.map +2 -2
- package/decorators/withDrag.d.ts +1 -1
- package/decorators/withDrag.js.map +1 -1
- package/decorators/withRelativePointer.d.ts +1 -1
- package/decorators/withRelativePointer.js.map +1 -1
- package/decorators/withResponsiveOptions.d.ts +3 -1
- package/decorators/withResponsiveOptions.js +22 -2
- package/decorators/withResponsiveOptions.js.map +2 -2
- package/helpers/createApp.js +5 -1
- package/helpers/createApp.js.map +2 -2
- package/package.json +1 -1
- package/services/AbstractService.d.ts +98 -0
- package/services/AbstractService.js +114 -0
- package/services/AbstractService.js.map +7 -0
- package/services/DragService.d.ts +124 -0
- package/services/DragService.js +217 -0
- package/services/DragService.js.map +7 -0
- package/services/KeyService.d.ts +29 -0
- package/services/KeyService.js +48 -0
- package/services/KeyService.js.map +7 -0
- package/services/LoadService.d.ts +15 -0
- package/services/LoadService.js +19 -0
- package/services/LoadService.js.map +7 -0
- package/services/PointerService.d.ts +56 -0
- package/services/PointerService.js +129 -0
- package/services/PointerService.js.map +7 -0
- package/services/RafService.d.ts +19 -0
- package/services/RafService.js +45 -0
- package/services/RafService.js.map +7 -0
- package/services/ResizeService.d.ts +29 -0
- package/services/ResizeService.js +66 -0
- package/services/ResizeService.js.map +7 -0
- package/services/{scroll.d.ts → ScrollService.d.ts} +14 -3
- package/services/ScrollService.js +90 -0
- package/services/ScrollService.js.map +7 -0
- package/services/index.d.ts +8 -41
- package/services/index.js +8 -18
- package/services/index.js.map +3 -3
- package/services/utils.d.ts +14 -0
- package/services/utils.js +11 -0
- package/services/utils.js.map +7 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/index.js.map +2 -2
- package/utils/loadElement.d.ts +42 -0
- package/utils/loadElement.js +33 -0
- package/utils/loadElement.js.map +7 -0
- package/utils/tween.js +1 -1
- package/utils/tween.js.map +2 -2
- package/services/drag.d.ts +0 -75
- package/services/drag.js +0 -199
- package/services/drag.js.map +0 -7
- package/services/key.d.ts +0 -21
- package/services/key.js +0 -65
- package/services/key.js.map +0 -7
- package/services/load.d.ts +0 -11
- package/services/load.js +0 -38
- package/services/load.js.map +0 -7
- package/services/pointer.d.ts +0 -32
- package/services/pointer.js +0 -123
- package/services/pointer.js.map +0 -7
- package/services/raf.d.ts +0 -9
- package/services/raf.js +0 -56
- package/services/raf.js.map +0 -7
- package/services/resize.d.ts +0 -15
- package/services/resize.js +0 -67
- package/services/resize.js.map +0 -7
- package/services/scroll.js +0 -105
- package/services/scroll.js.map +0 -7
- package/services/service.d.ts +0 -16
- package/services/service.js +0 -47
- package/services/service.js.map +0 -7
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { AbstractService } from "./AbstractService.js";
|
|
2
|
+
import { useRaf } from "./RafService.js";
|
|
3
|
+
import { isDefined, inertiaFinalValue } from "../utils/index.js";
|
|
4
|
+
import { PASSIVE_EVENT_OPTIONS, CAPTURE_EVENT_OPTIONS } from "./utils.js";
|
|
5
|
+
let count = 0;
|
|
6
|
+
class DragService extends AbstractService {
|
|
7
|
+
static MODES = {
|
|
8
|
+
START: "start",
|
|
9
|
+
DRAG: "drag",
|
|
10
|
+
DROP: "drop",
|
|
11
|
+
INERTIA: "inertia",
|
|
12
|
+
STOP: "stop"
|
|
13
|
+
};
|
|
14
|
+
static config = [
|
|
15
|
+
[
|
|
16
|
+
(instance) => instance.props.target,
|
|
17
|
+
[
|
|
18
|
+
["dragstart", CAPTURE_EVENT_OPTIONS],
|
|
19
|
+
["click", CAPTURE_EVENT_OPTIONS],
|
|
20
|
+
["pointerdown", PASSIVE_EVENT_OPTIONS]
|
|
21
|
+
]
|
|
22
|
+
],
|
|
23
|
+
[
|
|
24
|
+
() => window,
|
|
25
|
+
[
|
|
26
|
+
["pointerup", PASSIVE_EVENT_OPTIONS],
|
|
27
|
+
["touchend", PASSIVE_EVENT_OPTIONS]
|
|
28
|
+
]
|
|
29
|
+
]
|
|
30
|
+
];
|
|
31
|
+
id;
|
|
32
|
+
dampFactor = 0.85;
|
|
33
|
+
dragTreshold = 10;
|
|
34
|
+
previousEvent = null;
|
|
35
|
+
props = {
|
|
36
|
+
target: null,
|
|
37
|
+
mode: void 0,
|
|
38
|
+
isGrabbing: false,
|
|
39
|
+
hasInertia: false,
|
|
40
|
+
x: 0,
|
|
41
|
+
y: 0,
|
|
42
|
+
delta: {
|
|
43
|
+
x: 0,
|
|
44
|
+
y: 0
|
|
45
|
+
},
|
|
46
|
+
origin: {
|
|
47
|
+
x: 0,
|
|
48
|
+
y: 0
|
|
49
|
+
},
|
|
50
|
+
distance: {
|
|
51
|
+
x: 0,
|
|
52
|
+
y: 0
|
|
53
|
+
},
|
|
54
|
+
final: {
|
|
55
|
+
x: 0,
|
|
56
|
+
y: 0
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Test if we should allow click on links and buttons.
|
|
61
|
+
*/
|
|
62
|
+
get shouldPreventClick() {
|
|
63
|
+
return Math.abs(this.props.distance.x) > this.dragTreshold || Math.abs(this.props.distance.y) > this.dragTreshold;
|
|
64
|
+
}
|
|
65
|
+
constructor(target, { dampFactor = 0.85, dragTreshold = 10 } = {}) {
|
|
66
|
+
super();
|
|
67
|
+
count += 1;
|
|
68
|
+
this.id = `drag-${count}`;
|
|
69
|
+
this.dampFactor = dampFactor;
|
|
70
|
+
this.dragTreshold = dragTreshold;
|
|
71
|
+
this.props.target = target;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get the client value for the given axis.
|
|
75
|
+
*/
|
|
76
|
+
getEventPosition(event) {
|
|
77
|
+
const eventOrTouch = isDefined(event.touches) ? event.touches[0] : event;
|
|
78
|
+
return {
|
|
79
|
+
x: eventOrTouch.clientX,
|
|
80
|
+
y: eventOrTouch.clientY
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Start the drag.
|
|
85
|
+
*
|
|
86
|
+
* @param {number} x The initial horizontal position.
|
|
87
|
+
* @param {number} y The initial vertical position.
|
|
88
|
+
*/
|
|
89
|
+
start(x, y) {
|
|
90
|
+
const { props } = this;
|
|
91
|
+
if (props.isGrabbing) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
props.x = props.origin.x = props.final.x = x;
|
|
95
|
+
props.y = props.origin.y = props.final.y = y;
|
|
96
|
+
props.delta.x = props.distance.x = 0;
|
|
97
|
+
props.delta.y = props.distance.y = 0;
|
|
98
|
+
props.mode = DragService.MODES.START;
|
|
99
|
+
props.isGrabbing = true;
|
|
100
|
+
this.trigger(props);
|
|
101
|
+
document.addEventListener("touchmove", this, PASSIVE_EVENT_OPTIONS);
|
|
102
|
+
document.addEventListener("mousemove", this, PASSIVE_EVENT_OPTIONS);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Stop the drag, or drop.
|
|
106
|
+
*/
|
|
107
|
+
drop() {
|
|
108
|
+
const { props, dampFactor, id } = this;
|
|
109
|
+
if (!props.isGrabbing) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
document.removeEventListener("touchmove", this);
|
|
113
|
+
document.removeEventListener("mousemove", this);
|
|
114
|
+
props.isGrabbing = false;
|
|
115
|
+
props.mode = DragService.MODES.DROP;
|
|
116
|
+
props.hasInertia = true;
|
|
117
|
+
props.final.x = inertiaFinalValue(props.x, props.delta.x, dampFactor);
|
|
118
|
+
props.final.y = inertiaFinalValue(props.y, props.delta.y, dampFactor);
|
|
119
|
+
this.previousEvent = null;
|
|
120
|
+
this.trigger(props);
|
|
121
|
+
setTimeout(() => {
|
|
122
|
+
const raf = useRaf();
|
|
123
|
+
raf.remove(id);
|
|
124
|
+
raf.add(id, () => this.rafHandler());
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Stop the drag.
|
|
129
|
+
*/
|
|
130
|
+
stop() {
|
|
131
|
+
const { props, id } = this;
|
|
132
|
+
useRaf().remove(id);
|
|
133
|
+
props.isGrabbing = false;
|
|
134
|
+
props.hasInertia = false;
|
|
135
|
+
props.mode = DragService.MODES.STOP;
|
|
136
|
+
this.trigger(props);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Raf service handler.
|
|
140
|
+
*/
|
|
141
|
+
rafHandler() {
|
|
142
|
+
const { props, dampFactor } = this;
|
|
143
|
+
if (!props.isGrabbing) {
|
|
144
|
+
props.x += props.delta.x;
|
|
145
|
+
props.y += props.delta.y;
|
|
146
|
+
props.distance.x = props.x - props.origin.x;
|
|
147
|
+
props.distance.y = props.y - props.origin.y;
|
|
148
|
+
props.delta.x *= dampFactor;
|
|
149
|
+
props.delta.y *= dampFactor;
|
|
150
|
+
props.mode = DragService.MODES.INERTIA;
|
|
151
|
+
this.trigger(props);
|
|
152
|
+
if (Math.abs(props.delta.x) < 0.1 && Math.abs(props.delta.y) < 0.1) {
|
|
153
|
+
this.stop();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Pointer service handler.
|
|
159
|
+
*/
|
|
160
|
+
drag(event) {
|
|
161
|
+
const { props } = this;
|
|
162
|
+
if (props.isGrabbing) {
|
|
163
|
+
const position = this.getEventPosition(event);
|
|
164
|
+
props.x = position.x;
|
|
165
|
+
props.y = position.y;
|
|
166
|
+
if (this.previousEvent) {
|
|
167
|
+
const previousPosition = this.getEventPosition(this.previousEvent);
|
|
168
|
+
props.delta.x = position.x - previousPosition.x;
|
|
169
|
+
props.delta.y = position.y - previousPosition.y;
|
|
170
|
+
}
|
|
171
|
+
props.final.x = position.x;
|
|
172
|
+
props.final.y = position.y;
|
|
173
|
+
props.distance.x = props.x - props.origin.x;
|
|
174
|
+
props.distance.y = props.y - props.origin.y;
|
|
175
|
+
props.mode = DragService.MODES.DRAG;
|
|
176
|
+
this.trigger(props);
|
|
177
|
+
this.previousEvent = event;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Handle any event.
|
|
182
|
+
*/
|
|
183
|
+
handleEvent(event) {
|
|
184
|
+
switch (event.type) {
|
|
185
|
+
case "dragstart":
|
|
186
|
+
event.preventDefault();
|
|
187
|
+
break;
|
|
188
|
+
case "click":
|
|
189
|
+
if (this.shouldPreventClick) {
|
|
190
|
+
event.stopImmediatePropagation();
|
|
191
|
+
event.stopPropagation();
|
|
192
|
+
event.preventDefault();
|
|
193
|
+
}
|
|
194
|
+
break;
|
|
195
|
+
case "pointerup":
|
|
196
|
+
case "touchend":
|
|
197
|
+
this.drop();
|
|
198
|
+
break;
|
|
199
|
+
case "touchmove":
|
|
200
|
+
case "mousemove":
|
|
201
|
+
this.drag(event);
|
|
202
|
+
break;
|
|
203
|
+
default:
|
|
204
|
+
if (event.button === 0) {
|
|
205
|
+
this.start(event.x, event.y);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function useDrag(target, options) {
|
|
211
|
+
return DragService.getInstance(target, target, options);
|
|
212
|
+
}
|
|
213
|
+
export {
|
|
214
|
+
DragService,
|
|
215
|
+
useDrag
|
|
216
|
+
};
|
|
217
|
+
//# sourceMappingURL=DragService.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../packages/js-toolkit/services/DragService.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ServiceConfig, ServiceInterface } from './AbstractService.js';\nimport { AbstractService } from './AbstractService.js';\nimport { useRaf } from './RafService.js';\nimport { isDefined, inertiaFinalValue } from '../utils/index.js';\nimport { PASSIVE_EVENT_OPTIONS, CAPTURE_EVENT_OPTIONS } from './utils.js';\n\ntype DragLifecycle = 'start' | 'drag' | 'drop' | 'inertia' | 'stop';\n\nexport interface DragServiceProps {\n /**\n * The current mode of the dragging logic.\n */\n mode: DragLifecycle;\n /**\n * The target element of the drag.\n */\n target: HTMLElement;\n /**\n * Whether the user is currently grabbing the targeted element or not.\n */\n isGrabbing: boolean;\n /**\n * Whether the drag currently has inertia or not.\n */\n hasInertia: boolean;\n /**\n * The current horizontal position in the viewport.\n */\n x: number;\n /**\n * The current vertical position in the viewport.\n */\n y: number;\n /**\n * The delta between the current position and the last.\n */\n delta: { x: number; y: number };\n /**\n * The initial position where the dragging started.\n */\n origin: { x: number; y: number };\n /**\n * The distance from the current position to the origin.\n */\n distance: { x: number; y: number };\n /**\n * The final position that will be reached at the end of the inertia.\n */\n final: { x: number; y: number };\n}\n\nexport type DragServiceInterface = ServiceInterface<DragServiceProps>;\n\nexport interface DragServiceOptions {\n dampFactor?: number;\n dragTreshold?: number;\n}\n\nlet count = 0;\n\nexport class DragService extends AbstractService<DragServiceProps> {\n static MODES: Record<Uppercase<DragLifecycle>, DragLifecycle> = {\n START: 'start',\n DRAG: 'drag',\n DROP: 'drop',\n INERTIA: 'inertia',\n STOP: 'stop',\n };\n\n static config: ServiceConfig = [\n [\n (instance) => (instance as DragService).props.target,\n [\n ['dragstart', CAPTURE_EVENT_OPTIONS],\n ['click', CAPTURE_EVENT_OPTIONS],\n ['pointerdown', PASSIVE_EVENT_OPTIONS],\n ],\n ],\n [\n () => window,\n [\n ['pointerup', PASSIVE_EVENT_OPTIONS],\n ['touchend', PASSIVE_EVENT_OPTIONS],\n ],\n ],\n ];\n\n id: string;\n\n dampFactor = 0.85;\n\n dragTreshold = 10;\n\n previousEvent: TouchEvent | MouseEvent = null;\n\n props = {\n target: null,\n mode: undefined,\n isGrabbing: false,\n hasInertia: false,\n x: 0,\n y: 0,\n delta: {\n x: 0,\n y: 0,\n },\n origin: {\n x: 0,\n y: 0,\n },\n distance: {\n x: 0,\n y: 0,\n },\n final: {\n x: 0,\n y: 0,\n },\n } as DragServiceProps;\n\n /**\n * Test if we should allow click on links and buttons.\n */\n get shouldPreventClick(): boolean {\n return (\n Math.abs(this.props.distance.x) > this.dragTreshold ||\n Math.abs(this.props.distance.y) > this.dragTreshold\n );\n }\n\n constructor(\n target: HTMLElement,\n { dampFactor = 0.85, dragTreshold = 10 }: DragServiceOptions = {},\n ) {\n super();\n count += 1;\n this.id = `drag-${count}`;\n this.dampFactor = dampFactor;\n this.dragTreshold = dragTreshold;\n this.props.target = target;\n }\n\n /**\n * Get the client value for the given axis.\n */\n getEventPosition(event: MouseEvent | TouchEvent): { x: number; y: number } {\n // @ts-ignore\n const eventOrTouch = isDefined(event.touches) ? event.touches[0] : event;\n return {\n x: eventOrTouch.clientX,\n y: eventOrTouch.clientY,\n };\n }\n\n /**\n * Start the drag.\n *\n * @param {number} x The initial horizontal position.\n * @param {number} y The initial vertical position.\n */\n start(x: number, y: number) {\n const { props } = this;\n if (props.isGrabbing) {\n return;\n }\n\n // Reset state\n props.x = props.origin.x = props.final.x = x;\n props.y = props.origin.y = props.final.y = y;\n props.delta.x = props.distance.x = 0;\n props.delta.y = props.distance.y = 0;\n props.mode = DragService.MODES.START;\n props.isGrabbing = true;\n\n this.trigger(props);\n\n document.addEventListener('touchmove', this, PASSIVE_EVENT_OPTIONS);\n document.addEventListener('mousemove', this, PASSIVE_EVENT_OPTIONS);\n }\n\n /**\n * Stop the drag, or drop.\n */\n drop() {\n const { props, dampFactor, id } = this;\n\n if (!props.isGrabbing) {\n return;\n }\n\n document.removeEventListener('touchmove', this);\n document.removeEventListener('mousemove', this);\n\n props.isGrabbing = false;\n props.mode = DragService.MODES.DROP;\n props.hasInertia = true;\n props.final.x = inertiaFinalValue(props.x, props.delta.x, dampFactor);\n props.final.y = inertiaFinalValue(props.y, props.delta.y, dampFactor);\n this.previousEvent = null;\n\n this.trigger(props);\n\n setTimeout(() => {\n const raf = useRaf();\n raf.remove(id);\n raf.add(id, () => this.rafHandler());\n });\n }\n\n /**\n * Stop the drag.\n */\n stop() {\n const { props, id } = this;\n\n useRaf().remove(id);\n props.isGrabbing = false;\n props.hasInertia = false;\n props.mode = DragService.MODES.STOP;\n\n this.trigger(props);\n }\n\n /**\n * Raf service handler.\n */\n rafHandler() {\n const { props, dampFactor } = this;\n\n if (!props.isGrabbing) {\n props.x += props.delta.x;\n props.y += props.delta.y;\n props.distance.x = props.x - props.origin.x;\n props.distance.y = props.y - props.origin.y;\n props.delta.x *= dampFactor;\n props.delta.y *= dampFactor;\n props.mode = DragService.MODES.INERTIA;\n\n this.trigger(props);\n\n if (Math.abs(props.delta.x) < 0.1 && Math.abs(props.delta.y) < 0.1) {\n this.stop();\n }\n }\n }\n\n /**\n * Pointer service handler.\n */\n drag(event: TouchEvent | MouseEvent) {\n const { props } = this;\n\n if (props.isGrabbing) {\n const position = this.getEventPosition(event);\n props.x = position.x;\n props.y = position.y;\n\n if (this.previousEvent) {\n const previousPosition = this.getEventPosition(this.previousEvent);\n props.delta.x = position.x - previousPosition.x;\n props.delta.y = position.y - previousPosition.y;\n }\n\n props.final.x = position.x;\n props.final.y = position.y;\n props.distance.x = props.x - props.origin.x;\n props.distance.y = props.y - props.origin.y;\n props.mode = DragService.MODES.DRAG;\n\n this.trigger(props);\n this.previousEvent = event;\n }\n }\n\n /**\n * Handle any event.\n */\n handleEvent(event: MouseEvent | PointerEvent | DragEvent) {\n switch (event.type) {\n case 'dragstart':\n event.preventDefault();\n break;\n case 'click':\n if (this.shouldPreventClick) {\n event.stopImmediatePropagation();\n event.stopPropagation();\n event.preventDefault();\n }\n break;\n case 'pointerup':\n case 'touchend':\n this.drop();\n break;\n case 'touchmove':\n case 'mousemove':\n this.drag(event);\n break;\n default:\n if (event.button === 0) {\n this.start(event.x, event.y);\n }\n }\n }\n}\n\n/**\n * Use the drag service.\n *\n * ```js\n * import { useDrag } from '@studiometa/js-toolkit/services';\n * const element = document.querySelector('.draggable');\n * const { add, remove, props } = useDrag(element, { dampFactor: 0.5 });\n * add('key', (props) => console.log(props));\n * remove('key');\n * props();\n * ```\n */\nexport function useDrag(target: HTMLElement, options: DragServiceOptions): DragServiceInterface {\n return DragService.getInstance<DragServiceInterface>(target, target, options);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ServiceConfig, ServiceInterface } from './AbstractService.js';
|
|
2
|
+
import { AbstractService } from './AbstractService.js';
|
|
3
|
+
export interface KeyServiceProps {
|
|
4
|
+
event: KeyboardEvent;
|
|
5
|
+
triggered: number;
|
|
6
|
+
direction: 'up' | 'down' | 'none';
|
|
7
|
+
isUp: boolean;
|
|
8
|
+
isDown: boolean;
|
|
9
|
+
ENTER: boolean;
|
|
10
|
+
SPACE: boolean;
|
|
11
|
+
TAB: boolean;
|
|
12
|
+
ESC: boolean;
|
|
13
|
+
LEFT: boolean;
|
|
14
|
+
UP: boolean;
|
|
15
|
+
RIGHT: boolean;
|
|
16
|
+
DOWN: boolean;
|
|
17
|
+
}
|
|
18
|
+
export type KeyServiceInterface = ServiceInterface<KeyServiceProps>;
|
|
19
|
+
export declare class KeyService extends AbstractService<KeyServiceProps> {
|
|
20
|
+
static config: ServiceConfig;
|
|
21
|
+
previousEvent: Event | null;
|
|
22
|
+
props: KeyServiceProps;
|
|
23
|
+
updateProps(event: KeyboardEvent): KeyServiceProps;
|
|
24
|
+
handleEvent(event: KeyboardEvent): void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Use the keyboard service.
|
|
28
|
+
*/
|
|
29
|
+
export declare function useKey(): KeyServiceInterface;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { AbstractService } from "./AbstractService.js";
|
|
2
|
+
import keyCodes from "../utils/keyCodes.js";
|
|
3
|
+
function getInitialKeyCodes() {
|
|
4
|
+
return Object.fromEntries(Object.keys(keyCodes).map((key) => [key, false]));
|
|
5
|
+
}
|
|
6
|
+
class KeyService extends AbstractService {
|
|
7
|
+
static config = [[() => document, [["keydown"], ["keyup"]]]];
|
|
8
|
+
previousEvent = null;
|
|
9
|
+
props = {
|
|
10
|
+
event: null,
|
|
11
|
+
triggered: 0,
|
|
12
|
+
isUp: false,
|
|
13
|
+
isDown: false,
|
|
14
|
+
direction: "none",
|
|
15
|
+
...getInitialKeyCodes()
|
|
16
|
+
};
|
|
17
|
+
updateProps(event) {
|
|
18
|
+
const { props } = this;
|
|
19
|
+
props.event = event;
|
|
20
|
+
for (const [name, code] of Object.entries(keyCodes)) {
|
|
21
|
+
props[name] = code === event.keyCode;
|
|
22
|
+
}
|
|
23
|
+
if (!this.previousEvent) {
|
|
24
|
+
props.triggered = 0;
|
|
25
|
+
}
|
|
26
|
+
if (props.event.type === "keydown" && this.previousEvent?.type === "keydown") {
|
|
27
|
+
props.triggered += 1;
|
|
28
|
+
} else {
|
|
29
|
+
props.triggered = 1;
|
|
30
|
+
}
|
|
31
|
+
this.previousEvent = props.event;
|
|
32
|
+
props.direction = props.event.type === "keydown" ? "down" : "up";
|
|
33
|
+
props.isUp = props.event.type === "keyup";
|
|
34
|
+
props.isDown = props.event.type === "keydown";
|
|
35
|
+
return props;
|
|
36
|
+
}
|
|
37
|
+
handleEvent(event) {
|
|
38
|
+
this.trigger(this.updateProps(event));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function useKey() {
|
|
42
|
+
return KeyService.getInstance();
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
KeyService,
|
|
46
|
+
useKey
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=KeyService.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../packages/js-toolkit/services/KeyService.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ServiceConfig, ServiceInterface } from './AbstractService.js';\nimport { AbstractService } from './AbstractService.js';\nimport keyCodes from '../utils/keyCodes.js';\n\nfunction getInitialKeyCodes(): Record<keyof typeof keyCodes, false> {\n return Object.fromEntries(Object.keys(keyCodes).map((key) => [key, false])) as Record<\n keyof typeof keyCodes,\n false\n >;\n}\n\nexport interface KeyServiceProps {\n event: KeyboardEvent;\n triggered: number;\n direction: 'up' | 'down' | 'none';\n isUp: boolean;\n isDown: boolean;\n ENTER: boolean;\n SPACE: boolean;\n TAB: boolean;\n ESC: boolean;\n LEFT: boolean;\n UP: boolean;\n RIGHT: boolean;\n DOWN: boolean;\n}\n\nexport type KeyServiceInterface = ServiceInterface<KeyServiceProps>;\n\nexport class KeyService extends AbstractService<KeyServiceProps> {\n static config: ServiceConfig = [[() => document, [['keydown'], ['keyup']]]];\n\n previousEvent: Event | null = null;\n\n props: KeyServiceProps = {\n event: null,\n triggered: 0,\n isUp: false,\n isDown: false,\n direction: 'none',\n ...getInitialKeyCodes(),\n };\n\n updateProps(event: KeyboardEvent): KeyServiceProps {\n const { props } = this;\n\n props.event = event;\n\n for (const [name, code] of Object.entries(keyCodes)) {\n props[name] = code === event.keyCode;\n }\n\n if (!this.previousEvent) {\n props.triggered = 0;\n }\n\n if (props.event.type === 'keydown' && this.previousEvent?.type === 'keydown') {\n props.triggered += 1;\n } else {\n props.triggered = 1;\n }\n\n this.previousEvent = props.event;\n\n props.direction = props.event.type === 'keydown' ? 'down' : 'up';\n props.isUp = props.event.type === 'keyup';\n props.isDown = props.event.type === 'keydown';\n\n return props;\n }\n\n handleEvent(event: KeyboardEvent) {\n this.trigger(this.updateProps(event));\n }\n}\n\n/**\n * Use the keyboard service.\n */\nexport function useKey(): KeyServiceInterface {\n return KeyService.getInstance();\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,uBAAuB;AAChC,OAAO,cAAc;AAErB,SAAS,qBAA2D;AAClE,SAAO,OAAO,YAAY,OAAO,KAAK,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,CAAC;AAI5E;AAoBO,MAAM,mBAAmB,gBAAiC;AAAA,EAC/D,OAAO,SAAwB,CAAC,CAAC,MAAM,UAAU,CAAC,CAAC,SAAS,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AAAA,EAE1E,gBAA8B;AAAA,EAE9B,QAAyB;AAAA,IACvB,OAAO;AAAA,IACP,WAAW;AAAA,IACX,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,GAAG,mBAAmB;AAAA,EACxB;AAAA,EAEA,YAAY,OAAuC;AACjD,UAAM,EAAE,MAAM,IAAI;AAElB,UAAM,QAAQ;AAEd,eAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,YAAM,IAAI,IAAI,SAAS,MAAM;AAAA,IAC/B;AAEA,QAAI,CAAC,KAAK,eAAe;AACvB,YAAM,YAAY;AAAA,IACpB;AAEA,QAAI,MAAM,MAAM,SAAS,aAAa,KAAK,eAAe,SAAS,WAAW;AAC5E,YAAM,aAAa;AAAA,IACrB,OAAO;AACL,YAAM,YAAY;AAAA,IACpB;AAEA,SAAK,gBAAgB,MAAM;AAE3B,UAAM,YAAY,MAAM,MAAM,SAAS,YAAY,SAAS;AAC5D,UAAM,OAAO,MAAM,MAAM,SAAS;AAClC,UAAM,SAAS,MAAM,MAAM,SAAS;AAEpC,WAAO;AAAA,EACT;AAAA,EAEA,YAAY,OAAsB;AAChC,SAAK,QAAQ,KAAK,YAAY,KAAK,CAAC;AAAA,EACtC;AACF;AAKO,SAAS,SAA8B;AAC5C,SAAO,WAAW,YAAY;AAChC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ServiceInterface, ServiceConfig } from './AbstractService.js';
|
|
2
|
+
import { AbstractService } from './AbstractService.js';
|
|
3
|
+
export interface LoadServiceProps {
|
|
4
|
+
time: DOMHighResTimeStamp;
|
|
5
|
+
}
|
|
6
|
+
export type LoadServiceInterface = ServiceInterface<LoadServiceProps>;
|
|
7
|
+
export declare class LoadService extends AbstractService<LoadServiceProps> {
|
|
8
|
+
static config: ServiceConfig;
|
|
9
|
+
props: LoadServiceProps;
|
|
10
|
+
handleEvent(): void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Use the load service.
|
|
14
|
+
*/
|
|
15
|
+
export declare function useLoad(): LoadServiceInterface;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { AbstractService } from "./AbstractService.js";
|
|
2
|
+
class LoadService extends AbstractService {
|
|
3
|
+
static config = [[() => window, [["load"]]]];
|
|
4
|
+
props = {
|
|
5
|
+
time: performance.now()
|
|
6
|
+
};
|
|
7
|
+
handleEvent() {
|
|
8
|
+
this.props.time = window.performance.now();
|
|
9
|
+
this.trigger(this.props);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function useLoad() {
|
|
13
|
+
return LoadService.getInstance();
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
LoadService,
|
|
17
|
+
useLoad
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=LoadService.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../packages/js-toolkit/services/LoadService.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ServiceInterface, ServiceConfig } from './AbstractService.js';\nimport { AbstractService } from './AbstractService.js';\n\nexport interface LoadServiceProps {\n time: DOMHighResTimeStamp;\n}\n\nexport type LoadServiceInterface = ServiceInterface<LoadServiceProps>;\n\nexport class LoadService extends AbstractService<LoadServiceProps> {\n static config: ServiceConfig = [[() => window, [['load']]]];\n\n props: LoadServiceProps = {\n time: performance.now(),\n };\n\n handleEvent() {\n this.props.time = window.performance.now();\n this.trigger(this.props);\n }\n}\n\n/**\n * Use the load service.\n */\nexport function useLoad(): LoadServiceInterface {\n return LoadService.getInstance();\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,uBAAuB;AAQzB,MAAM,oBAAoB,gBAAkC;AAAA,EACjE,OAAO,SAAwB,CAAC,CAAC,MAAM,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAAA,EAE1D,QAA0B;AAAA,IACxB,MAAM,YAAY,IAAI;AAAA,EACxB;AAAA,EAEA,cAAc;AACZ,SAAK,MAAM,OAAO,OAAO,YAAY,IAAI;AACzC,SAAK,QAAQ,KAAK,KAAK;AAAA,EACzB;AACF;AAKO,SAAS,UAAgC;AAC9C,SAAO,YAAY,YAAY;AACjC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ServiceConfig, ServiceInterface } from './AbstractService.js';
|
|
2
|
+
import { AbstractService } from './AbstractService.js';
|
|
3
|
+
export interface PointerServiceProps {
|
|
4
|
+
event: MouseEvent | TouchEvent;
|
|
5
|
+
isDown: boolean;
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
changed: {
|
|
9
|
+
x: boolean;
|
|
10
|
+
y: boolean;
|
|
11
|
+
};
|
|
12
|
+
last: {
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
};
|
|
16
|
+
delta: {
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
};
|
|
20
|
+
progress: {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
};
|
|
24
|
+
max: {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export type PointerServiceInterface = ServiceInterface<PointerServiceProps>;
|
|
30
|
+
export declare class PointerService extends AbstractService<PointerServiceProps> {
|
|
31
|
+
static config: ServiceConfig;
|
|
32
|
+
target: HTMLElement | Window | undefined;
|
|
33
|
+
props: PointerServiceProps;
|
|
34
|
+
constructor(target: HTMLElement | undefined);
|
|
35
|
+
isTouchEvent(event: TouchEvent | MouseEvent): boolean;
|
|
36
|
+
getTargetSize(): DOMRect | {
|
|
37
|
+
width: number;
|
|
38
|
+
height: number;
|
|
39
|
+
x: number;
|
|
40
|
+
y: number;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Update the pointer positions.
|
|
44
|
+
*/
|
|
45
|
+
updateProps(event: MouseEvent | TouchEvent): PointerServiceProps;
|
|
46
|
+
/**
|
|
47
|
+
* Handle events.
|
|
48
|
+
*
|
|
49
|
+
* @todo handle scroll as well
|
|
50
|
+
*/
|
|
51
|
+
handleEvent(event: MouseEvent | TouchEvent): void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Use the pointer service.
|
|
55
|
+
*/
|
|
56
|
+
export declare function usePointer(target?: HTMLElement | Window): PointerServiceInterface;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { AbstractService } from "./AbstractService.js";
|
|
2
|
+
import { ONCE_CAPTURE_EVENT_OPTIONS, PASSIVE_CAPTURE_EVENT_OPTIONS } from "./utils.js";
|
|
3
|
+
class PointerService extends AbstractService {
|
|
4
|
+
static config = [
|
|
5
|
+
[
|
|
6
|
+
() => document,
|
|
7
|
+
[
|
|
8
|
+
["mouseenter", ONCE_CAPTURE_EVENT_OPTIONS],
|
|
9
|
+
["mousemove", PASSIVE_CAPTURE_EVENT_OPTIONS],
|
|
10
|
+
["touchmove", PASSIVE_CAPTURE_EVENT_OPTIONS],
|
|
11
|
+
["mousedown", PASSIVE_CAPTURE_EVENT_OPTIONS],
|
|
12
|
+
["touchstart", PASSIVE_CAPTURE_EVENT_OPTIONS],
|
|
13
|
+
["mouseup", PASSIVE_CAPTURE_EVENT_OPTIONS],
|
|
14
|
+
["touchend", PASSIVE_CAPTURE_EVENT_OPTIONS]
|
|
15
|
+
]
|
|
16
|
+
]
|
|
17
|
+
];
|
|
18
|
+
target;
|
|
19
|
+
props = {
|
|
20
|
+
event: null,
|
|
21
|
+
isDown: false,
|
|
22
|
+
x: 0,
|
|
23
|
+
y: 0,
|
|
24
|
+
changed: {
|
|
25
|
+
x: false,
|
|
26
|
+
y: false
|
|
27
|
+
},
|
|
28
|
+
last: {
|
|
29
|
+
x: 0,
|
|
30
|
+
y: 0
|
|
31
|
+
},
|
|
32
|
+
delta: {
|
|
33
|
+
x: 0,
|
|
34
|
+
y: 0
|
|
35
|
+
},
|
|
36
|
+
progress: {
|
|
37
|
+
x: 0.5,
|
|
38
|
+
y: 0.5
|
|
39
|
+
},
|
|
40
|
+
max: {
|
|
41
|
+
x: 0,
|
|
42
|
+
y: 0
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
constructor(target) {
|
|
46
|
+
super();
|
|
47
|
+
this.target = target;
|
|
48
|
+
const targetSize = this.getTargetSize();
|
|
49
|
+
this.props.x = this.props.last.x = targetSize.x / 2;
|
|
50
|
+
this.props.y = this.props.last.y = targetSize.y / 2;
|
|
51
|
+
this.props.max.x = targetSize.width;
|
|
52
|
+
this.props.max.y = targetSize.height;
|
|
53
|
+
}
|
|
54
|
+
isTouchEvent(event) {
|
|
55
|
+
return typeof TouchEvent !== "undefined" && event instanceof TouchEvent;
|
|
56
|
+
}
|
|
57
|
+
getTargetSize() {
|
|
58
|
+
const { target } = this;
|
|
59
|
+
return target instanceof Element ? target.getBoundingClientRect() : {
|
|
60
|
+
width: window.innerWidth,
|
|
61
|
+
height: window.innerHeight,
|
|
62
|
+
x: 0,
|
|
63
|
+
y: 0
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Update the pointer positions.
|
|
68
|
+
*/
|
|
69
|
+
updateProps(event) {
|
|
70
|
+
const { props } = this;
|
|
71
|
+
props.event = event;
|
|
72
|
+
const yLast = props.y;
|
|
73
|
+
const xLast = props.x;
|
|
74
|
+
const targetSize = this.getTargetSize();
|
|
75
|
+
let y = this.isTouchEvent(event) ? event.touches[0]?.clientY : event.clientY;
|
|
76
|
+
y -= targetSize.y;
|
|
77
|
+
if (y !== props.y) {
|
|
78
|
+
props.y = y;
|
|
79
|
+
}
|
|
80
|
+
let x = this.isTouchEvent(event) ? event.touches[0]?.clientX : event.clientX;
|
|
81
|
+
x -= targetSize.x;
|
|
82
|
+
if (x !== props.x) {
|
|
83
|
+
props.x = x;
|
|
84
|
+
}
|
|
85
|
+
props.changed.x = props.x !== xLast;
|
|
86
|
+
props.changed.y = props.y !== yLast;
|
|
87
|
+
props.last.x = xLast;
|
|
88
|
+
props.last.y = yLast;
|
|
89
|
+
props.delta.x = props.x - xLast;
|
|
90
|
+
props.delta.y = props.y - yLast;
|
|
91
|
+
props.max.x = targetSize.width;
|
|
92
|
+
props.max.y = targetSize.height;
|
|
93
|
+
props.progress.x = props.x / props.max.x;
|
|
94
|
+
props.progress.y = props.y / props.max.y;
|
|
95
|
+
return props;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Handle events.
|
|
99
|
+
*
|
|
100
|
+
* @todo handle scroll as well
|
|
101
|
+
*/
|
|
102
|
+
handleEvent(event) {
|
|
103
|
+
switch (event.type) {
|
|
104
|
+
case "mouseenter":
|
|
105
|
+
case "mousemove":
|
|
106
|
+
case "touchmove":
|
|
107
|
+
this.trigger(this.updateProps(event));
|
|
108
|
+
break;
|
|
109
|
+
case "mousedown":
|
|
110
|
+
case "touchstart":
|
|
111
|
+
this.props.isDown = true;
|
|
112
|
+
this.trigger(this.props);
|
|
113
|
+
break;
|
|
114
|
+
case "mouseup":
|
|
115
|
+
case "touchend":
|
|
116
|
+
this.props.isDown = false;
|
|
117
|
+
this.trigger(this.props);
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function usePointer(target = window) {
|
|
123
|
+
return PointerService.getInstance(target, target);
|
|
124
|
+
}
|
|
125
|
+
export {
|
|
126
|
+
PointerService,
|
|
127
|
+
usePointer
|
|
128
|
+
};
|
|
129
|
+
//# sourceMappingURL=PointerService.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../packages/js-toolkit/services/PointerService.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ServiceConfig, ServiceInterface } from './AbstractService.js';\nimport { AbstractService } from './AbstractService.js';\nimport { ONCE_CAPTURE_EVENT_OPTIONS, PASSIVE_CAPTURE_EVENT_OPTIONS } from './utils.js';\n\nexport interface PointerServiceProps {\n event: MouseEvent | TouchEvent;\n isDown: boolean;\n x: number;\n y: number;\n changed: { x: boolean; y: boolean };\n last: { x: number; y: number };\n delta: { x: number; y: number };\n progress: { x: number; y: number };\n max: { x: number; y: number };\n}\n\nexport type PointerServiceInterface = ServiceInterface<PointerServiceProps>;\n\nexport class PointerService extends AbstractService<PointerServiceProps> {\n static config: ServiceConfig = [\n [\n () => document,\n [\n ['mouseenter', ONCE_CAPTURE_EVENT_OPTIONS],\n ['mousemove', PASSIVE_CAPTURE_EVENT_OPTIONS],\n ['touchmove', PASSIVE_CAPTURE_EVENT_OPTIONS],\n ['mousedown', PASSIVE_CAPTURE_EVENT_OPTIONS],\n ['touchstart', PASSIVE_CAPTURE_EVENT_OPTIONS],\n ['mouseup', PASSIVE_CAPTURE_EVENT_OPTIONS],\n ['touchend', PASSIVE_CAPTURE_EVENT_OPTIONS],\n ],\n ],\n ];\n\n target: HTMLElement | Window | undefined;\n\n props: PointerServiceProps = {\n event: null,\n isDown: false,\n x: 0,\n y: 0,\n changed: {\n x: false,\n y: false,\n },\n last: {\n x: 0,\n y: 0,\n },\n delta: {\n x: 0,\n y: 0,\n },\n progress: {\n x: 0.5,\n y: 0.5,\n },\n max: {\n x: 0,\n y: 0,\n },\n };\n\n constructor(target: HTMLElement | undefined) {\n super();\n this.target = target;\n const targetSize = this.getTargetSize();\n this.props.x = this.props.last.x = targetSize.x / 2;\n this.props.y = this.props.last.y = targetSize.y / 2;\n this.props.max.x = targetSize.width;\n this.props.max.y = targetSize.height;\n }\n\n isTouchEvent(event: TouchEvent | MouseEvent): boolean {\n return typeof TouchEvent !== 'undefined' && event instanceof TouchEvent;\n }\n\n getTargetSize() {\n const { target } = this;\n return target instanceof Element\n ? target.getBoundingClientRect()\n : {\n width: window.innerWidth,\n height: window.innerHeight,\n x: 0,\n y: 0,\n };\n }\n\n /**\n * Update the pointer positions.\n */\n updateProps(event: MouseEvent | TouchEvent): PointerServiceProps {\n const { props } = this;\n\n props.event = event;\n const yLast = props.y;\n const xLast = props.x;\n\n const targetSize = this.getTargetSize();\n\n // Check pointer Y\n // We either get data from a touch event `event.touches[0].clientY` or from\n // a mouse event `event.clientY`.\n let y = this.isTouchEvent(event)\n ? (event as TouchEvent).touches[0]?.clientY\n : (event as MouseEvent).clientY;\n y -= targetSize.y;\n if (y !== props.y) {\n props.y = y;\n }\n\n // Check pointer X\n // We either get data from a touch event `event.touches[0].clientX` or from\n // a mouse event `event.clientX`.\n let x = this.isTouchEvent(event)\n ? (event as TouchEvent).touches[0]?.clientX\n : (event as MouseEvent).clientX;\n x -= targetSize.x;\n if (x !== props.x) {\n props.x = x;\n }\n\n props.changed.x = props.x !== xLast;\n props.changed.y = props.y !== yLast;\n\n props.last.x = xLast;\n props.last.y = yLast;\n\n props.delta.x = props.x - xLast;\n props.delta.y = props.y - yLast;\n\n props.max.x = targetSize.width;\n props.max.y = targetSize.height;\n\n props.progress.x = props.x / props.max.x;\n props.progress.y = props.y / props.max.y;\n\n return props;\n }\n\n /**\n * Handle events.\n *\n * @todo handle scroll as well\n */\n handleEvent(event: MouseEvent | TouchEvent) {\n // eslint-disable-next-line default-case\n switch (event.type) {\n case 'mouseenter':\n case 'mousemove':\n case 'touchmove':\n this.trigger(this.updateProps(event));\n break;\n case 'mousedown':\n case 'touchstart':\n this.props.isDown = true;\n this.trigger(this.props);\n break;\n case 'mouseup':\n case 'touchend':\n this.props.isDown = false;\n this.trigger(this.props);\n break;\n }\n }\n}\n\n/**\n * Use the pointer service.\n */\nexport function usePointer(target: HTMLElement | Window = window): PointerServiceInterface {\n return PointerService.getInstance(target, target);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ServiceInterface } from './AbstractService.js';
|
|
2
|
+
import { AbstractService } from './AbstractService.js';
|
|
3
|
+
export interface RafServiceProps {
|
|
4
|
+
time: DOMHighResTimeStamp;
|
|
5
|
+
}
|
|
6
|
+
export type RafServiceInterface = ServiceInterface<RafServiceProps>;
|
|
7
|
+
export declare class RafService extends AbstractService<RafServiceProps> {
|
|
8
|
+
isTicking: boolean;
|
|
9
|
+
scheduler: Record<"update" | "render", (fn: () => unknown) => void>;
|
|
10
|
+
props: RafServiceProps;
|
|
11
|
+
trigger(props: RafServiceProps): void;
|
|
12
|
+
loop(): void;
|
|
13
|
+
init(): void;
|
|
14
|
+
kill(): void;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Use the RequestAnimationFrame (raf) service.
|
|
18
|
+
*/
|
|
19
|
+
export declare function useRaf(): RafServiceInterface;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { AbstractService } from "./AbstractService.js";
|
|
2
|
+
import { useScheduler } from "../utils/scheduler.js";
|
|
3
|
+
import { isFunction } from "../utils/is.js";
|
|
4
|
+
class RafService extends AbstractService {
|
|
5
|
+
isTicking = false;
|
|
6
|
+
scheduler = useScheduler(["update", "render"]);
|
|
7
|
+
props = {
|
|
8
|
+
time: performance.now()
|
|
9
|
+
};
|
|
10
|
+
trigger(props) {
|
|
11
|
+
for (const callback of this.callbacks.values()) {
|
|
12
|
+
this.scheduler.update(() => {
|
|
13
|
+
const render = callback(props);
|
|
14
|
+
if (isFunction(render)) {
|
|
15
|
+
this.scheduler.render(() => {
|
|
16
|
+
render(props);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
loop() {
|
|
23
|
+
this.props.time = performance.now();
|
|
24
|
+
this.trigger(this.props);
|
|
25
|
+
if (!this.isTicking) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
requestAnimationFrame(() => this.loop());
|
|
29
|
+
}
|
|
30
|
+
init() {
|
|
31
|
+
this.isTicking = true;
|
|
32
|
+
requestAnimationFrame(() => this.loop());
|
|
33
|
+
}
|
|
34
|
+
kill() {
|
|
35
|
+
this.isTicking = false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function useRaf() {
|
|
39
|
+
return RafService.getInstance();
|
|
40
|
+
}
|
|
41
|
+
export {
|
|
42
|
+
RafService,
|
|
43
|
+
useRaf
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=RafService.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../packages/js-toolkit/services/RafService.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ServiceInterface } from './AbstractService.js';\nimport { AbstractService } from './AbstractService.js';\nimport { useScheduler } from '../utils/scheduler.js';\nimport { isFunction } from '../utils/is.js';\n\nexport interface RafServiceProps {\n time: DOMHighResTimeStamp;\n}\n\nexport type RafServiceInterface = ServiceInterface<RafServiceProps>;\n\nexport class RafService extends AbstractService<RafServiceProps> {\n isTicking = false;\n scheduler = useScheduler(['update', 'render']);\n\n props: RafServiceProps = {\n time: performance.now(),\n };\n\n trigger(props: RafServiceProps) {\n for (const callback of this.callbacks.values()) {\n this.scheduler.update(() => {\n const render = callback(props) as (() => unknown) | void;\n if (isFunction(render)) {\n this.scheduler.render(() => {\n // @ts-ignore\n render(props);\n });\n }\n });\n }\n }\n\n loop() {\n this.props.time = performance.now();\n this.trigger(this.props);\n\n if (!this.isTicking) {\n return;\n }\n\n requestAnimationFrame(() => this.loop());\n }\n\n init() {\n this.isTicking = true;\n requestAnimationFrame(() => this.loop());\n }\n kill() {\n this.isTicking = false;\n }\n}\n\n/**\n * Use the RequestAnimationFrame (raf) service.\n */\nexport function useRaf(): RafServiceInterface {\n return RafService.getInstance();\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,kBAAkB;AAQpB,MAAM,mBAAmB,gBAAiC;AAAA,EAC/D,YAAY;AAAA,EACZ,YAAY,aAAa,CAAC,UAAU,QAAQ,CAAC;AAAA,EAE7C,QAAyB;AAAA,IACvB,MAAM,YAAY,IAAI;AAAA,EACxB;AAAA,EAEA,QAAQ,OAAwB;AAC9B,eAAW,YAAY,KAAK,UAAU,OAAO,GAAG;AAC9C,WAAK,UAAU,OAAO,MAAM;AAC1B,cAAM,SAAS,SAAS,KAAK;AAC7B,YAAI,WAAW,MAAM,GAAG;AACtB,eAAK,UAAU,OAAO,MAAM;AAE1B,mBAAO,KAAK;AAAA,UACd,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,OAAO;AACL,SAAK,MAAM,OAAO,YAAY,IAAI;AAClC,SAAK,QAAQ,KAAK,KAAK;AAEvB,QAAI,CAAC,KAAK,WAAW;AACnB;AAAA,IACF;AAEA,0BAAsB,MAAM,KAAK,KAAK,CAAC;AAAA,EACzC;AAAA,EAEA,OAAO;AACL,SAAK,YAAY;AACjB,0BAAsB,MAAM,KAAK,KAAK,CAAC;AAAA,EACzC;AAAA,EACA,OAAO;AACL,SAAK,YAAY;AAAA,EACnB;AACF;AAKO,SAAS,SAA8B;AAC5C,SAAO,WAAW,YAAY;AAChC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|