@studiometa/js-toolkit 3.0.3 → 3.0.4
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/package.json
CHANGED
|
@@ -70,6 +70,13 @@ export interface DragServiceOptions {
|
|
|
70
70
|
dragTreshold?: number;
|
|
71
71
|
}
|
|
72
72
|
export declare class DragService extends AbstractService<DragServiceProps> {
|
|
73
|
+
static MODES: {
|
|
74
|
+
readonly START: "start";
|
|
75
|
+
readonly DRAG: "drag";
|
|
76
|
+
readonly DROP: "drop";
|
|
77
|
+
readonly INERTIA: "inertia";
|
|
78
|
+
readonly STOP: "stop";
|
|
79
|
+
};
|
|
73
80
|
static config: ServiceConfig;
|
|
74
81
|
id: string;
|
|
75
82
|
dampFactor: number;
|
package/services/DragService.js
CHANGED
|
@@ -5,6 +5,13 @@ import { inertiaFinalValue } from "../utils/math/index.js";
|
|
|
5
5
|
import { PASSIVE_EVENT_OPTIONS, CAPTURE_EVENT_OPTIONS } from "./utils.js";
|
|
6
6
|
let count = 0;
|
|
7
7
|
class DragService extends AbstractService {
|
|
8
|
+
static MODES = {
|
|
9
|
+
START: "start",
|
|
10
|
+
DRAG: "drag",
|
|
11
|
+
DROP: "drop",
|
|
12
|
+
INERTIA: "inertia",
|
|
13
|
+
STOP: "stop"
|
|
14
|
+
};
|
|
8
15
|
static config = [
|
|
9
16
|
[
|
|
10
17
|
(instance) => instance.props.target,
|
|
@@ -29,13 +36,7 @@ class DragService extends AbstractService {
|
|
|
29
36
|
props = {
|
|
30
37
|
target: null,
|
|
31
38
|
mode: void 0,
|
|
32
|
-
MODES:
|
|
33
|
-
START: "start",
|
|
34
|
-
DRAG: "drag",
|
|
35
|
-
DROP: "drop",
|
|
36
|
-
INERTIA: "inertia",
|
|
37
|
-
STOP: "stop"
|
|
38
|
-
},
|
|
39
|
+
MODES: DragService.MODES,
|
|
39
40
|
isGrabbing: false,
|
|
40
41
|
hasInertia: false,
|
|
41
42
|
x: 0,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
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 } from '../utils/is.js';\nimport { inertiaFinalValue } from '../utils/math/index.js';\nimport { PASSIVE_EVENT_OPTIONS, CAPTURE_EVENT_OPTIONS } from './utils.js';\n\nexport interface DragServiceProps {\n /**\n * The current mode of the dragging logic.\n */\n mode: 'start' | 'drag' | 'drop' | 'inertia' | 'stop';\n /**\n * Available modes.\n */\n MODES: {\n START: 'start';\n DRAG: 'drag';\n DROP: 'drop';\n INERTIA: 'inertia';\n STOP: 'stop';\n };\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 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 MODES:
|
|
5
|
-
"mappings": "AACA,SAAS,uBAAuB;AAChC,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAClC,SAAS,uBAAuB,6BAA6B;AA8D7D,IAAI,QAAQ;AAEL,MAAM,oBAAoB,gBAAkC;AAAA,EACjE,OAAO,SAAwB;AAAA,IAC7B;AAAA,MACE,CAAC,aAAc,SAAyB,MAAM;AAAA,MAC9C;AAAA,QACE,CAAC,aAAa,qBAAqB;AAAA,QACnC,CAAC,SAAS,qBAAqB;AAAA,QAC/B,CAAC,eAAe,qBAAqB;AAAA,MACvC;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN;AAAA,QACE,CAAC,aAAa,qBAAqB;AAAA,QACnC,CAAC,YAAY,qBAAqB;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AAAA,EAEA;AAAA,EAEA,aAAa;AAAA,EAEb,eAAe;AAAA,EAEf,gBAAyC;AAAA,EAEzC,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO
|
|
4
|
+
"sourcesContent": ["import type { ServiceConfig, ServiceInterface } from './AbstractService.js';\nimport { AbstractService } from './AbstractService.js';\nimport { useRaf } from './RafService.js';\nimport { isDefined } from '../utils/is.js';\nimport { inertiaFinalValue } from '../utils/math/index.js';\nimport { PASSIVE_EVENT_OPTIONS, CAPTURE_EVENT_OPTIONS } from './utils.js';\n\nexport interface DragServiceProps {\n /**\n * The current mode of the dragging logic.\n */\n mode: 'start' | 'drag' | 'drop' | 'inertia' | 'stop';\n /**\n * Available modes.\n */\n MODES: {\n START: 'start';\n DRAG: 'drag';\n DROP: 'drop';\n INERTIA: 'inertia';\n STOP: 'stop';\n };\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 = {\n START: 'start',\n DRAG: 'drag',\n DROP: 'drop',\n INERTIA: 'inertia',\n STOP: 'stop',\n } as const;\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 MODES: DragService.MODES,\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 = props.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 = props.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 = props.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 = props.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 = props.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>(\n [target, JSON.stringify(options)],\n target,\n options,\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|