@studiometa/js-toolkit 2.6.3 → 2.6.5
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 +1 -1
- package/services/drag.cjs +2 -1
- package/services/drag.cjs.map +2 -2
- package/services/drag.js +2 -1
- package/services/drag.js.map +2 -2
- package/utils/tween.cjs +1 -1
- package/utils/tween.cjs.map +1 -1
- package/utils/tween.js +1 -1
- package/utils/tween.js.map +1 -1
package/package.json
CHANGED
package/services/drag.cjs
CHANGED
|
@@ -40,7 +40,7 @@ var MODES = {
|
|
|
40
40
|
STOP: "stop"
|
|
41
41
|
};
|
|
42
42
|
var count = 0;
|
|
43
|
-
var events = ["pointerdown", "pointerup"];
|
|
43
|
+
var events = ["pointerdown", "pointerup", "touchend"];
|
|
44
44
|
var passiveEventOptions = { passive: true };
|
|
45
45
|
function getEventPosition(event) {
|
|
46
46
|
const eventOrTouch = (0, import_utils.isDefined)(event.touches) ? event.touches[0] : event;
|
|
@@ -149,6 +149,7 @@ function createDragService(target, { dampFactor = 0.85, dragTreshold = 10 } = {}
|
|
|
149
149
|
}
|
|
150
150
|
break;
|
|
151
151
|
case "pointerup":
|
|
152
|
+
case "touchend":
|
|
152
153
|
drop();
|
|
153
154
|
break;
|
|
154
155
|
case "touchmove":
|
package/services/drag.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../packages/js-toolkit/services/drag.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable no-use-before-define */\nimport { useService } from './service.js';\nimport useRaf from './raf.js';\nimport inertiaFinalValue from '../utils/math/inertiaFinalValue.js';\n// eslint-disable-next-line import/extensions\nimport { isDefined } from '../utils/index.js';\n\n/**\n * @typedef {import('./index').ServiceInterface<DragServiceProps>} DragService\n * @typedef {import('./pointer.js').PointerServiceProps} PointerServiceProps\n * @typedef {'start'|'drag'|'drop'|'inertia'|'stop'} DragLifecycle\n * @typedef {Object} DragServiceProps\n * @property {DragLifecycle} mode\n * The current mode of the dragging logic.\n * @property {HTMLElement} target\n * The target element of the drag.\n * @property {boolean} isGrabbing\n * Whether the user is currently grabbing the targeted element or not.\n * @property {boolean} hasInertia\n * Whether the drag currently has inertia or not.\n * @property {number} x\n * The current horizontal position in the viewport.\n * @property {number} y\n * The current vertical position in the viewport.\n * @property {{ x: number, y: number }} delta\n * The delta between the current position and the last.\n * @property {{ x: number, y: number }} origin\n * The initial position where the dragging started.\n * @property {{ x: number, y: number }} distance\n * The distance from the current position to the origin.\n * @property {{ x: number, y: number }} final\n * The final position that will be reached at the end of the inertia.\n * @typedef {Object} DragServiceOptions\n * @property {number} [dampFactor]\n * @property {number} [dragTreshold]\n */\n\n/**\n * @type {Record<Uppercase<DragLifecycle>, DragLifecycle>}\n */\nconst MODES = {\n START: 'start',\n DRAG: 'drag',\n DROP: 'drop',\n INERTIA: 'inertia',\n STOP: 'stop',\n};\n\nlet count = 0;\nconst events = ['pointerdown', 'pointerup'];\nconst passiveEventOptions = { passive: true };\n\n/**\n * Get the client value for the given axis.\n * @param {MouseEvent|TouchEvent} event\n * @returns {{ x: number, y: number }}\n */\nfunction getEventPosition(event) {\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 * Get drag service.\n * @param {HTMLElement} target\n * @param {Object} options\n * @param {number} [options.dampFactor]\n * @param {number} [options.dragTreshold]\n * @returns {DragService}\n */\nfunction createDragService(target, { dampFactor = 0.85, dragTreshold = 10 } = {}) {\n count += 1;\n const id = `drag-${count}`;\n let previousEvent;\n\n /**\n * Test if we should allow click on links and buttons.\n *\n * @private\n * @returns {boolean}\n */\n function shouldPreventClick() {\n return Math.abs(props.distance.x) > dragTreshold || Math.abs(props.distance.y) > dragTreshold;\n }\n\n /**\n * Start the drag.\n * @param {number} x The initial horizontal position.\n * @param {number} y The initial vertical position.\n * @returns {void}\n */\n function start(x, y) {\n if (props.isGrabbing) {\n return;\n }\n\n // Reset state\n props.x = x;\n props.y = y;\n props.origin.x = x;\n props.origin.y = y;\n props.delta.x = 0;\n props.delta.y = 0;\n props.distance.x = 0;\n props.distance.y = 0;\n props.final.x = x;\n props.final.y = y;\n\n props.mode = MODES.START;\n\n // Enable grabbing\n props.isGrabbing = true;\n\n trigger(props);\n\n document.addEventListener('touchmove', handleEvent, passiveEventOptions);\n document.addEventListener('mousemove', handleEvent, passiveEventOptions);\n }\n\n /**\n * Stop the drag, or drop.\n * @returns {void}\n */\n function drop() {\n document.removeEventListener('touchmove', handleEvent);\n document.removeEventListener('mousemove', handleEvent);\n props.isGrabbing = false;\n props.mode = MODES.DROP;\n\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\n trigger(props);\n\n setTimeout(() => {\n const raf = useRaf();\n raf.remove(id);\n raf.add(id, rafHandler);\n }, 0);\n }\n\n /**\n * Stop the drag.\n */\n function stop() {\n useRaf().remove(id);\n props.isGrabbing = false;\n props.hasInertia = false;\n props.mode = MODES.STOP;\n trigger(props);\n }\n\n /**\n * Raf service handler.\n * @returns {void}\n */\n function rafHandler() {\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\n props.delta.x *= dampFactor;\n props.delta.y *= dampFactor;\n\n if (props.mode !== MODES.INERTIA) {\n props.mode = MODES.INERTIA;\n }\n\n trigger(props);\n\n if (Math.abs(props.delta.x) < 0.1 && Math.abs(props.delta.y) < 0.1) {\n stop();\n }\n }\n }\n\n /**\n * Pointer service handler.\n * @param {TouchEvent|MouseEvent} event\n * @returns {void}\n */\n function drag(event) {\n if (props.isGrabbing) {\n const position = getEventPosition(event);\n props.x = position.x;\n props.y = position.y;\n\n if (previousEvent) {\n const previousPosition = getEventPosition(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\n if (props.mode !== MODES.DRAG) {\n props.mode = MODES.DRAG;\n }\n\n trigger(props);\n previousEvent = event;\n }\n }\n\n /**\n * Handle any event.\n * @param {MouseEvent|PointerEvent|DragEvent} event\n */\n function handleEvent(event) {\n switch (event.type) {\n case 'dragstart':\n event.preventDefault();\n break;\n case 'click':\n if (shouldPreventClick()) {\n event.stopImmediatePropagation();\n event.stopPropagation();\n event.preventDefault();\n }\n break;\n case 'pointerup':\n drop();\n break;\n case 'touchmove':\n case 'mousemove':\n drag(event);\n break;\n default:\n if (event.button === 0) {\n start(event.x, event.y);\n }\n }\n }\n\n const { add, remove, has, trigger, props } = useService({\n /**\n * @type {DragServiceProps}\n */\n props: {\n target,\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 },\n init() {\n events.forEach((event) => {\n target.addEventListener(event, handleEvent, passiveEventOptions);\n });\n target.addEventListener('dragstart', handleEvent, { capture: true });\n target.addEventListener('click', handleEvent, { capture: true });\n },\n kill() {\n events.forEach((event) => {\n target.removeEventListener(event, handleEvent);\n });\n target.removeEventListener('dragstart', handleEvent);\n target.removeEventListener('click', handleEvent);\n },\n });\n\n return {\n add,\n remove,\n has,\n props: () => props,\n };\n}\n\n/**\n * @type {WeakMap<HTMLElement, DragService | undefined>}\n */\nconst instances = new WeakMap();\n\n/**\n * Use the drag service.\n *\n * ```js\n * import { useDrag } from '@studiometa/js-toolkit/services';\n * const { add, remove, props } = useDrag();\n * const draggableElement = document.querySelector('.draggable');\n * add(draggableElement, (props) => {}, { factor: 0.8 });\n * remove(draggableElement);\n * props(draggableElement);\n * ```\n *\n * @param {HTMLElement} target\n * @param {DragServiceOptions} options\n * @returns {DragService}\n */\nexport default function useDrag(target, options) {\n if (!instances.has(target)) {\n instances.set(target, createDragService(target, options));\n }\n\n return instances.get(target);\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,qBAA2B;AAC3B,iBAAmB;AACnB,+BAA8B;AAE9B,mBAA0B;AAmC1B,IAAM,QAAQ;AAAA,EACZ,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AACR;AAEA,IAAI,QAAQ;AACZ,IAAM,SAAS,CAAC,eAAe,
|
|
4
|
+
"sourcesContent": ["/* eslint-disable no-use-before-define */\nimport { useService } from './service.js';\nimport useRaf from './raf.js';\nimport inertiaFinalValue from '../utils/math/inertiaFinalValue.js';\n// eslint-disable-next-line import/extensions\nimport { isDefined } from '../utils/index.js';\n\n/**\n * @typedef {import('./index').ServiceInterface<DragServiceProps>} DragService\n * @typedef {import('./pointer.js').PointerServiceProps} PointerServiceProps\n * @typedef {'start'|'drag'|'drop'|'inertia'|'stop'} DragLifecycle\n * @typedef {Object} DragServiceProps\n * @property {DragLifecycle} mode\n * The current mode of the dragging logic.\n * @property {HTMLElement} target\n * The target element of the drag.\n * @property {boolean} isGrabbing\n * Whether the user is currently grabbing the targeted element or not.\n * @property {boolean} hasInertia\n * Whether the drag currently has inertia or not.\n * @property {number} x\n * The current horizontal position in the viewport.\n * @property {number} y\n * The current vertical position in the viewport.\n * @property {{ x: number, y: number }} delta\n * The delta between the current position and the last.\n * @property {{ x: number, y: number }} origin\n * The initial position where the dragging started.\n * @property {{ x: number, y: number }} distance\n * The distance from the current position to the origin.\n * @property {{ x: number, y: number }} final\n * The final position that will be reached at the end of the inertia.\n * @typedef {Object} DragServiceOptions\n * @property {number} [dampFactor]\n * @property {number} [dragTreshold]\n */\n\n/**\n * @type {Record<Uppercase<DragLifecycle>, DragLifecycle>}\n */\nconst MODES = {\n START: 'start',\n DRAG: 'drag',\n DROP: 'drop',\n INERTIA: 'inertia',\n STOP: 'stop',\n};\n\nlet count = 0;\nconst events = ['pointerdown', 'pointerup', 'touchend'];\nconst passiveEventOptions = { passive: true };\n\n/**\n * Get the client value for the given axis.\n * @param {MouseEvent|TouchEvent} event\n * @returns {{ x: number, y: number }}\n */\nfunction getEventPosition(event) {\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 * Get drag service.\n * @param {HTMLElement} target\n * @param {Object} options\n * @param {number} [options.dampFactor]\n * @param {number} [options.dragTreshold]\n * @returns {DragService}\n */\nfunction createDragService(target, { dampFactor = 0.85, dragTreshold = 10 } = {}) {\n count += 1;\n const id = `drag-${count}`;\n let previousEvent;\n\n /**\n * Test if we should allow click on links and buttons.\n *\n * @private\n * @returns {boolean}\n */\n function shouldPreventClick() {\n return Math.abs(props.distance.x) > dragTreshold || Math.abs(props.distance.y) > dragTreshold;\n }\n\n /**\n * Start the drag.\n * @param {number} x The initial horizontal position.\n * @param {number} y The initial vertical position.\n * @returns {void}\n */\n function start(x, y) {\n if (props.isGrabbing) {\n return;\n }\n\n // Reset state\n props.x = x;\n props.y = y;\n props.origin.x = x;\n props.origin.y = y;\n props.delta.x = 0;\n props.delta.y = 0;\n props.distance.x = 0;\n props.distance.y = 0;\n props.final.x = x;\n props.final.y = y;\n\n props.mode = MODES.START;\n\n // Enable grabbing\n props.isGrabbing = true;\n\n trigger(props);\n\n document.addEventListener('touchmove', handleEvent, passiveEventOptions);\n document.addEventListener('mousemove', handleEvent, passiveEventOptions);\n }\n\n /**\n * Stop the drag, or drop.\n * @returns {void}\n */\n function drop() {\n document.removeEventListener('touchmove', handleEvent);\n document.removeEventListener('mousemove', handleEvent);\n props.isGrabbing = false;\n props.mode = MODES.DROP;\n\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\n trigger(props);\n\n setTimeout(() => {\n const raf = useRaf();\n raf.remove(id);\n raf.add(id, rafHandler);\n }, 0);\n }\n\n /**\n * Stop the drag.\n */\n function stop() {\n useRaf().remove(id);\n props.isGrabbing = false;\n props.hasInertia = false;\n props.mode = MODES.STOP;\n trigger(props);\n }\n\n /**\n * Raf service handler.\n * @returns {void}\n */\n function rafHandler() {\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\n props.delta.x *= dampFactor;\n props.delta.y *= dampFactor;\n\n if (props.mode !== MODES.INERTIA) {\n props.mode = MODES.INERTIA;\n }\n\n trigger(props);\n\n if (Math.abs(props.delta.x) < 0.1 && Math.abs(props.delta.y) < 0.1) {\n stop();\n }\n }\n }\n\n /**\n * Pointer service handler.\n * @param {TouchEvent|MouseEvent} event\n * @returns {void}\n */\n function drag(event) {\n if (props.isGrabbing) {\n const position = getEventPosition(event);\n props.x = position.x;\n props.y = position.y;\n\n if (previousEvent) {\n const previousPosition = getEventPosition(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\n if (props.mode !== MODES.DRAG) {\n props.mode = MODES.DRAG;\n }\n\n trigger(props);\n previousEvent = event;\n }\n }\n\n /**\n * Handle any event.\n * @param {MouseEvent|PointerEvent|DragEvent} event\n */\n function handleEvent(event) {\n switch (event.type) {\n case 'dragstart':\n event.preventDefault();\n break;\n case 'click':\n if (shouldPreventClick()) {\n event.stopImmediatePropagation();\n event.stopPropagation();\n event.preventDefault();\n }\n break;\n case 'pointerup':\n case 'touchend':\n drop();\n break;\n case 'touchmove':\n case 'mousemove':\n drag(event);\n break;\n default:\n if (event.button === 0) {\n start(event.x, event.y);\n }\n }\n }\n\n const { add, remove, has, trigger, props } = useService({\n /**\n * @type {DragServiceProps}\n */\n props: {\n target,\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 },\n init() {\n events.forEach((event) => {\n target.addEventListener(event, handleEvent, passiveEventOptions);\n });\n target.addEventListener('dragstart', handleEvent, { capture: true });\n target.addEventListener('click', handleEvent, { capture: true });\n },\n kill() {\n events.forEach((event) => {\n target.removeEventListener(event, handleEvent);\n });\n target.removeEventListener('dragstart', handleEvent);\n target.removeEventListener('click', handleEvent);\n },\n });\n\n return {\n add,\n remove,\n has,\n props: () => props,\n };\n}\n\n/**\n * @type {WeakMap<HTMLElement, DragService | undefined>}\n */\nconst instances = new WeakMap();\n\n/**\n * Use the drag service.\n *\n * ```js\n * import { useDrag } from '@studiometa/js-toolkit/services';\n * const { add, remove, props } = useDrag();\n * const draggableElement = document.querySelector('.draggable');\n * add(draggableElement, (props) => {}, { factor: 0.8 });\n * remove(draggableElement);\n * props(draggableElement);\n * ```\n *\n * @param {HTMLElement} target\n * @param {DragServiceOptions} options\n * @returns {DragService}\n */\nexport default function useDrag(target, options) {\n if (!instances.has(target)) {\n instances.set(target, createDragService(target, options));\n }\n\n return instances.get(target);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["inertiaFinalValue", "useRaf"]
|
|
7
7
|
}
|
package/services/drag.js
CHANGED
|
@@ -10,7 +10,7 @@ const MODES = {
|
|
|
10
10
|
STOP: "stop"
|
|
11
11
|
};
|
|
12
12
|
let count = 0;
|
|
13
|
-
const events = ["pointerdown", "pointerup"];
|
|
13
|
+
const events = ["pointerdown", "pointerup", "touchend"];
|
|
14
14
|
const passiveEventOptions = { passive: true };
|
|
15
15
|
function getEventPosition(event) {
|
|
16
16
|
const eventOrTouch = isDefined(event.touches) ? event.touches[0] : event;
|
|
@@ -119,6 +119,7 @@ function createDragService(target, { dampFactor = 0.85, dragTreshold = 10 } = {}
|
|
|
119
119
|
}
|
|
120
120
|
break;
|
|
121
121
|
case "pointerup":
|
|
122
|
+
case "touchend":
|
|
122
123
|
drop();
|
|
123
124
|
break;
|
|
124
125
|
case "touchmove":
|
package/services/drag.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../packages/js-toolkit/services/drag.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable no-use-before-define */\nimport { useService } from './service.js';\nimport useRaf from './raf.js';\nimport inertiaFinalValue from '../utils/math/inertiaFinalValue.js';\n// eslint-disable-next-line import/extensions\nimport { isDefined } from '../utils/index.js';\n\n/**\n * @typedef {import('./index').ServiceInterface<DragServiceProps>} DragService\n * @typedef {import('./pointer.js').PointerServiceProps} PointerServiceProps\n * @typedef {'start'|'drag'|'drop'|'inertia'|'stop'} DragLifecycle\n * @typedef {Object} DragServiceProps\n * @property {DragLifecycle} mode\n * The current mode of the dragging logic.\n * @property {HTMLElement} target\n * The target element of the drag.\n * @property {boolean} isGrabbing\n * Whether the user is currently grabbing the targeted element or not.\n * @property {boolean} hasInertia\n * Whether the drag currently has inertia or not.\n * @property {number} x\n * The current horizontal position in the viewport.\n * @property {number} y\n * The current vertical position in the viewport.\n * @property {{ x: number, y: number }} delta\n * The delta between the current position and the last.\n * @property {{ x: number, y: number }} origin\n * The initial position where the dragging started.\n * @property {{ x: number, y: number }} distance\n * The distance from the current position to the origin.\n * @property {{ x: number, y: number }} final\n * The final position that will be reached at the end of the inertia.\n * @typedef {Object} DragServiceOptions\n * @property {number} [dampFactor]\n * @property {number} [dragTreshold]\n */\n\n/**\n * @type {Record<Uppercase<DragLifecycle>, DragLifecycle>}\n */\nconst MODES = {\n START: 'start',\n DRAG: 'drag',\n DROP: 'drop',\n INERTIA: 'inertia',\n STOP: 'stop',\n};\n\nlet count = 0;\nconst events = ['pointerdown', 'pointerup'];\nconst passiveEventOptions = { passive: true };\n\n/**\n * Get the client value for the given axis.\n * @param {MouseEvent|TouchEvent} event\n * @returns {{ x: number, y: number }}\n */\nfunction getEventPosition(event) {\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 * Get drag service.\n * @param {HTMLElement} target\n * @param {Object} options\n * @param {number} [options.dampFactor]\n * @param {number} [options.dragTreshold]\n * @returns {DragService}\n */\nfunction createDragService(target, { dampFactor = 0.85, dragTreshold = 10 } = {}) {\n count += 1;\n const id = `drag-${count}`;\n let previousEvent;\n\n /**\n * Test if we should allow click on links and buttons.\n *\n * @private\n * @returns {boolean}\n */\n function shouldPreventClick() {\n return Math.abs(props.distance.x) > dragTreshold || Math.abs(props.distance.y) > dragTreshold;\n }\n\n /**\n * Start the drag.\n * @param {number} x The initial horizontal position.\n * @param {number} y The initial vertical position.\n * @returns {void}\n */\n function start(x, y) {\n if (props.isGrabbing) {\n return;\n }\n\n // Reset state\n props.x = x;\n props.y = y;\n props.origin.x = x;\n props.origin.y = y;\n props.delta.x = 0;\n props.delta.y = 0;\n props.distance.x = 0;\n props.distance.y = 0;\n props.final.x = x;\n props.final.y = y;\n\n props.mode = MODES.START;\n\n // Enable grabbing\n props.isGrabbing = true;\n\n trigger(props);\n\n document.addEventListener('touchmove', handleEvent, passiveEventOptions);\n document.addEventListener('mousemove', handleEvent, passiveEventOptions);\n }\n\n /**\n * Stop the drag, or drop.\n * @returns {void}\n */\n function drop() {\n document.removeEventListener('touchmove', handleEvent);\n document.removeEventListener('mousemove', handleEvent);\n props.isGrabbing = false;\n props.mode = MODES.DROP;\n\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\n trigger(props);\n\n setTimeout(() => {\n const raf = useRaf();\n raf.remove(id);\n raf.add(id, rafHandler);\n }, 0);\n }\n\n /**\n * Stop the drag.\n */\n function stop() {\n useRaf().remove(id);\n props.isGrabbing = false;\n props.hasInertia = false;\n props.mode = MODES.STOP;\n trigger(props);\n }\n\n /**\n * Raf service handler.\n * @returns {void}\n */\n function rafHandler() {\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\n props.delta.x *= dampFactor;\n props.delta.y *= dampFactor;\n\n if (props.mode !== MODES.INERTIA) {\n props.mode = MODES.INERTIA;\n }\n\n trigger(props);\n\n if (Math.abs(props.delta.x) < 0.1 && Math.abs(props.delta.y) < 0.1) {\n stop();\n }\n }\n }\n\n /**\n * Pointer service handler.\n * @param {TouchEvent|MouseEvent} event\n * @returns {void}\n */\n function drag(event) {\n if (props.isGrabbing) {\n const position = getEventPosition(event);\n props.x = position.x;\n props.y = position.y;\n\n if (previousEvent) {\n const previousPosition = getEventPosition(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\n if (props.mode !== MODES.DRAG) {\n props.mode = MODES.DRAG;\n }\n\n trigger(props);\n previousEvent = event;\n }\n }\n\n /**\n * Handle any event.\n * @param {MouseEvent|PointerEvent|DragEvent} event\n */\n function handleEvent(event) {\n switch (event.type) {\n case 'dragstart':\n event.preventDefault();\n break;\n case 'click':\n if (shouldPreventClick()) {\n event.stopImmediatePropagation();\n event.stopPropagation();\n event.preventDefault();\n }\n break;\n case 'pointerup':\n drop();\n break;\n case 'touchmove':\n case 'mousemove':\n drag(event);\n break;\n default:\n if (event.button === 0) {\n start(event.x, event.y);\n }\n }\n }\n\n const { add, remove, has, trigger, props } = useService({\n /**\n * @type {DragServiceProps}\n */\n props: {\n target,\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 },\n init() {\n events.forEach((event) => {\n target.addEventListener(event, handleEvent, passiveEventOptions);\n });\n target.addEventListener('dragstart', handleEvent, { capture: true });\n target.addEventListener('click', handleEvent, { capture: true });\n },\n kill() {\n events.forEach((event) => {\n target.removeEventListener(event, handleEvent);\n });\n target.removeEventListener('dragstart', handleEvent);\n target.removeEventListener('click', handleEvent);\n },\n });\n\n return {\n add,\n remove,\n has,\n props: () => props,\n };\n}\n\n/**\n * @type {WeakMap<HTMLElement, DragService | undefined>}\n */\nconst instances = new WeakMap();\n\n/**\n * Use the drag service.\n *\n * ```js\n * import { useDrag } from '@studiometa/js-toolkit/services';\n * const { add, remove, props } = useDrag();\n * const draggableElement = document.querySelector('.draggable');\n * add(draggableElement, (props) => {}, { factor: 0.8 });\n * remove(draggableElement);\n * props(draggableElement);\n * ```\n *\n * @param {HTMLElement} target\n * @param {DragServiceOptions} options\n * @returns {DragService}\n */\nexport default function useDrag(target, options) {\n if (!instances.has(target)) {\n instances.set(target, createDragService(target, options));\n }\n\n return instances.get(target);\n}\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,kBAAkB;AAC3B,OAAO,YAAY;AACnB,OAAO,uBAAuB;AAE9B,SAAS,iBAAiB;AAmC1B,MAAM,QAAQ;AAAA,EACZ,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AACR;AAEA,IAAI,QAAQ;AACZ,MAAM,SAAS,CAAC,eAAe,
|
|
4
|
+
"sourcesContent": ["/* eslint-disable no-use-before-define */\nimport { useService } from './service.js';\nimport useRaf from './raf.js';\nimport inertiaFinalValue from '../utils/math/inertiaFinalValue.js';\n// eslint-disable-next-line import/extensions\nimport { isDefined } from '../utils/index.js';\n\n/**\n * @typedef {import('./index').ServiceInterface<DragServiceProps>} DragService\n * @typedef {import('./pointer.js').PointerServiceProps} PointerServiceProps\n * @typedef {'start'|'drag'|'drop'|'inertia'|'stop'} DragLifecycle\n * @typedef {Object} DragServiceProps\n * @property {DragLifecycle} mode\n * The current mode of the dragging logic.\n * @property {HTMLElement} target\n * The target element of the drag.\n * @property {boolean} isGrabbing\n * Whether the user is currently grabbing the targeted element or not.\n * @property {boolean} hasInertia\n * Whether the drag currently has inertia or not.\n * @property {number} x\n * The current horizontal position in the viewport.\n * @property {number} y\n * The current vertical position in the viewport.\n * @property {{ x: number, y: number }} delta\n * The delta between the current position and the last.\n * @property {{ x: number, y: number }} origin\n * The initial position where the dragging started.\n * @property {{ x: number, y: number }} distance\n * The distance from the current position to the origin.\n * @property {{ x: number, y: number }} final\n * The final position that will be reached at the end of the inertia.\n * @typedef {Object} DragServiceOptions\n * @property {number} [dampFactor]\n * @property {number} [dragTreshold]\n */\n\n/**\n * @type {Record<Uppercase<DragLifecycle>, DragLifecycle>}\n */\nconst MODES = {\n START: 'start',\n DRAG: 'drag',\n DROP: 'drop',\n INERTIA: 'inertia',\n STOP: 'stop',\n};\n\nlet count = 0;\nconst events = ['pointerdown', 'pointerup', 'touchend'];\nconst passiveEventOptions = { passive: true };\n\n/**\n * Get the client value for the given axis.\n * @param {MouseEvent|TouchEvent} event\n * @returns {{ x: number, y: number }}\n */\nfunction getEventPosition(event) {\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 * Get drag service.\n * @param {HTMLElement} target\n * @param {Object} options\n * @param {number} [options.dampFactor]\n * @param {number} [options.dragTreshold]\n * @returns {DragService}\n */\nfunction createDragService(target, { dampFactor = 0.85, dragTreshold = 10 } = {}) {\n count += 1;\n const id = `drag-${count}`;\n let previousEvent;\n\n /**\n * Test if we should allow click on links and buttons.\n *\n * @private\n * @returns {boolean}\n */\n function shouldPreventClick() {\n return Math.abs(props.distance.x) > dragTreshold || Math.abs(props.distance.y) > dragTreshold;\n }\n\n /**\n * Start the drag.\n * @param {number} x The initial horizontal position.\n * @param {number} y The initial vertical position.\n * @returns {void}\n */\n function start(x, y) {\n if (props.isGrabbing) {\n return;\n }\n\n // Reset state\n props.x = x;\n props.y = y;\n props.origin.x = x;\n props.origin.y = y;\n props.delta.x = 0;\n props.delta.y = 0;\n props.distance.x = 0;\n props.distance.y = 0;\n props.final.x = x;\n props.final.y = y;\n\n props.mode = MODES.START;\n\n // Enable grabbing\n props.isGrabbing = true;\n\n trigger(props);\n\n document.addEventListener('touchmove', handleEvent, passiveEventOptions);\n document.addEventListener('mousemove', handleEvent, passiveEventOptions);\n }\n\n /**\n * Stop the drag, or drop.\n * @returns {void}\n */\n function drop() {\n document.removeEventListener('touchmove', handleEvent);\n document.removeEventListener('mousemove', handleEvent);\n props.isGrabbing = false;\n props.mode = MODES.DROP;\n\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\n trigger(props);\n\n setTimeout(() => {\n const raf = useRaf();\n raf.remove(id);\n raf.add(id, rafHandler);\n }, 0);\n }\n\n /**\n * Stop the drag.\n */\n function stop() {\n useRaf().remove(id);\n props.isGrabbing = false;\n props.hasInertia = false;\n props.mode = MODES.STOP;\n trigger(props);\n }\n\n /**\n * Raf service handler.\n * @returns {void}\n */\n function rafHandler() {\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\n props.delta.x *= dampFactor;\n props.delta.y *= dampFactor;\n\n if (props.mode !== MODES.INERTIA) {\n props.mode = MODES.INERTIA;\n }\n\n trigger(props);\n\n if (Math.abs(props.delta.x) < 0.1 && Math.abs(props.delta.y) < 0.1) {\n stop();\n }\n }\n }\n\n /**\n * Pointer service handler.\n * @param {TouchEvent|MouseEvent} event\n * @returns {void}\n */\n function drag(event) {\n if (props.isGrabbing) {\n const position = getEventPosition(event);\n props.x = position.x;\n props.y = position.y;\n\n if (previousEvent) {\n const previousPosition = getEventPosition(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\n if (props.mode !== MODES.DRAG) {\n props.mode = MODES.DRAG;\n }\n\n trigger(props);\n previousEvent = event;\n }\n }\n\n /**\n * Handle any event.\n * @param {MouseEvent|PointerEvent|DragEvent} event\n */\n function handleEvent(event) {\n switch (event.type) {\n case 'dragstart':\n event.preventDefault();\n break;\n case 'click':\n if (shouldPreventClick()) {\n event.stopImmediatePropagation();\n event.stopPropagation();\n event.preventDefault();\n }\n break;\n case 'pointerup':\n case 'touchend':\n drop();\n break;\n case 'touchmove':\n case 'mousemove':\n drag(event);\n break;\n default:\n if (event.button === 0) {\n start(event.x, event.y);\n }\n }\n }\n\n const { add, remove, has, trigger, props } = useService({\n /**\n * @type {DragServiceProps}\n */\n props: {\n target,\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 },\n init() {\n events.forEach((event) => {\n target.addEventListener(event, handleEvent, passiveEventOptions);\n });\n target.addEventListener('dragstart', handleEvent, { capture: true });\n target.addEventListener('click', handleEvent, { capture: true });\n },\n kill() {\n events.forEach((event) => {\n target.removeEventListener(event, handleEvent);\n });\n target.removeEventListener('dragstart', handleEvent);\n target.removeEventListener('click', handleEvent);\n },\n });\n\n return {\n add,\n remove,\n has,\n props: () => props,\n };\n}\n\n/**\n * @type {WeakMap<HTMLElement, DragService | undefined>}\n */\nconst instances = new WeakMap();\n\n/**\n * Use the drag service.\n *\n * ```js\n * import { useDrag } from '@studiometa/js-toolkit/services';\n * const { add, remove, props } = useDrag();\n * const draggableElement = document.querySelector('.draggable');\n * add(draggableElement, (props) => {}, { factor: 0.8 });\n * remove(draggableElement);\n * props(draggableElement);\n * ```\n *\n * @param {HTMLElement} target\n * @param {DragServiceOptions} options\n * @returns {DragService}\n */\nexport default function useDrag(target, options) {\n if (!instances.has(target)) {\n instances.set(target, createDragService(target, options));\n }\n\n return instances.get(target);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/utils/tween.cjs
CHANGED
|
@@ -35,7 +35,7 @@ var import_is = require("./is.cjs");
|
|
|
35
35
|
var import_noop = require("./noop.cjs");
|
|
36
36
|
var import_raf = __toESM(require("../services/raf.cjs"), 1);
|
|
37
37
|
var id = 0;
|
|
38
|
-
var PROGRESS_PRECISION =
|
|
38
|
+
var PROGRESS_PRECISION = 0.01;
|
|
39
39
|
function normalizeEase(ease) {
|
|
40
40
|
if (!(0, import_is.isDefined)(ease)) {
|
|
41
41
|
return import_noop.noopValue;
|
package/utils/tween.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../packages/js-toolkit/utils/tween.js"],
|
|
4
|
-
"sourcesContent": ["import { cubicBezier } from '@motionone/easing';\nimport { lerp, map, clamp01 } from './math/index.js';\nimport { isDefined, isArray } from './is.js';\nimport { noop, noopValue as linear } from './noop.js';\nimport useRaf from '../services/raf.js';\n\nlet id = 0;\nconst PROGRESS_PRECISION = 0.
|
|
4
|
+
"sourcesContent": ["import { cubicBezier } from '@motionone/easing';\nimport { lerp, map, clamp01 } from './math/index.js';\nimport { isDefined, isArray } from './is.js';\nimport { noop, noopValue as linear } from './noop.js';\nimport useRaf from '../services/raf.js';\n\nlet id = 0;\nconst PROGRESS_PRECISION = 0.01;\n\n/**\n * @typedef {[number, number, number, number]} BezierCurve\n * @typedef {{\n * duration?: number;\n * easing?: import('./math/createEases.js').EasingFunction|BezierCurve;\n * onStart?: () => void;\n * onProgress?: (progress: number, easedProgress: number) => void;\n * onFinish?: (progress: number, easedProgress: number) => void;\n * }} TweenOptions\n */\n\n/**\n * Normalize a easing function with default fallbacks.\n * @param {((p:number) => number)|[number,number,number,number]} ease\n * @returns {(p:number) => number}\n */\nexport function normalizeEase(ease) {\n if (!isDefined(ease)) {\n return linear;\n }\n\n if (isArray(ease)) {\n return cubicBezier(...ease);\n }\n\n return ease;\n}\n\n/**\n * Tween from 0 to 1.\n * @param {(progress:number)=>any} callback\n * @param {TweenOptions} [options]\n * @returns {any}\n */\nexport function tween(callback, options = {}) {\n const raf = useRaf();\n\n let progressValue = 0;\n let easedProgress = 0;\n\n const ease = normalizeEase(options.easing);\n let duration = options.duration ?? 1;\n duration *= 1000;\n\n let startTime = performance.now();\n let endTime = startTime + duration;\n\n const key = `tw-${id}`;\n id += 1;\n\n const { onStart = noop, onProgress = noop, onFinish = noop } = options;\n let isRunning = false;\n\n /**\n * Pause the animation.\n *\n * @returns {void}\n */\n function pause() {\n isRunning = false;\n raf.remove(key);\n }\n\n /**\n * Set the progress value.\n *\n * @param {number} newProgress The new progress value.\n * @returns {number}\n */\n function progress(newProgress) {\n if (typeof newProgress === 'undefined') {\n return easedProgress;\n }\n\n progressValue = newProgress;\n easedProgress = ease(progressValue);\n\n // Stop when reaching precision\n if (Math.abs(1 - easedProgress) < PROGRESS_PRECISION) {\n progressValue = 1;\n easedProgress = 1;\n }\n\n callback(easedProgress);\n onProgress(progressValue, easedProgress);\n\n if (easedProgress === 1) {\n pause();\n requestAnimationFrame(() => onFinish(progressValue, easedProgress));\n }\n\n return progressValue;\n }\n\n /**\n * Loop for rendering the animation.\n *\n * @param {Object} props\n * @param {number} props.time\n * @returns {void}\n */\n function tick(props) {\n if (!isRunning) {\n raf.remove(key);\n return;\n }\n\n progress(clamp01(map(props.time, startTime, endTime, 0, 1)));\n }\n\n /**\n * Play the animation.\n *\n * @returns {void}\n */\n function start() {\n onStart();\n startTime = performance.now();\n endTime = startTime + duration;\n progressValue = 0;\n easedProgress = 0;\n isRunning = true;\n\n raf.add(key, tick);\n }\n\n /**\n * Play a paused animation.\n * @returns {void}\n */\n function play() {\n if (isRunning) {\n return;\n }\n\n startTime = performance.now() - lerp(0, duration, progressValue);\n endTime = startTime + duration;\n isRunning = true;\n\n raf.add(key, tick);\n }\n\n return {\n start,\n finish: () => progress(1),\n pause,\n play,\n progress,\n };\n}\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA4B;AAC5B,kBAAmC;AACnC,gBAAmC;AACnC,kBAA0C;AAC1C,iBAAmB;AAEnB,IAAI,KAAK;AACT,IAAM,qBAAqB;AAkBpB,SAAS,cAAc,MAAM;AAClC,MAAI,KAAC,qBAAU,IAAI,GAAG;AACpB,WAAO,YAAAA;AAAA,EACT;AAEA,UAAI,mBAAQ,IAAI,GAAG;AACjB,eAAO,2BAAY,GAAG,IAAI;AAAA,EAC5B;AAEA,SAAO;AACT;AAQO,SAAS,MAAM,UAAU,UAAU,CAAC,GAAG;AAC5C,QAAM,UAAM,WAAAC,SAAO;AAEnB,MAAI,gBAAgB;AACpB,MAAI,gBAAgB;AAEpB,QAAM,OAAO,cAAc,QAAQ,MAAM;AACzC,MAAI,WAAW,QAAQ,YAAY;AACnC,cAAY;AAEZ,MAAI,YAAY,YAAY,IAAI;AAChC,MAAI,UAAU,YAAY;AAE1B,QAAM,MAAM,MAAM;AAClB,QAAM;AAEN,QAAM,EAAE,UAAU,kBAAM,aAAa,kBAAM,WAAW,iBAAK,IAAI;AAC/D,MAAI,YAAY;AAOhB,WAAS,QAAQ;AACf,gBAAY;AACZ,QAAI,OAAO,GAAG;AAAA,EAChB;AAQA,WAAS,SAAS,aAAa;AAC7B,QAAI,OAAO,gBAAgB,aAAa;AACtC,aAAO;AAAA,IACT;AAEA,oBAAgB;AAChB,oBAAgB,KAAK,aAAa;AAGlC,QAAI,KAAK,IAAI,IAAI,aAAa,IAAI,oBAAoB;AACpD,sBAAgB;AAChB,sBAAgB;AAAA,IAClB;AAEA,aAAS,aAAa;AACtB,eAAW,eAAe,aAAa;AAEvC,QAAI,kBAAkB,GAAG;AACvB,YAAM;AACN,4BAAsB,MAAM,SAAS,eAAe,aAAa,CAAC;AAAA,IACpE;AAEA,WAAO;AAAA,EACT;AASA,WAAS,KAAK,OAAO;AACnB,QAAI,CAAC,WAAW;AACd,UAAI,OAAO,GAAG;AACd;AAAA,IACF;AAEA,iBAAS,yBAAQ,iBAAI,MAAM,MAAM,WAAW,SAAS,GAAG,CAAC,CAAC,CAAC;AAAA,EAC7D;AAOA,WAAS,QAAQ;AACf,YAAQ;AACR,gBAAY,YAAY,IAAI;AAC5B,cAAU,YAAY;AACtB,oBAAgB;AAChB,oBAAgB;AAChB,gBAAY;AAEZ,QAAI,IAAI,KAAK,IAAI;AAAA,EACnB;AAMA,WAAS,OAAO;AACd,QAAI,WAAW;AACb;AAAA,IACF;AAEA,gBAAY,YAAY,IAAI,QAAI,kBAAK,GAAG,UAAU,aAAa;AAC/D,cAAU,YAAY;AACtB,gBAAY;AAEZ,QAAI,IAAI,KAAK,IAAI;AAAA,EACnB;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,MAAM,SAAS,CAAC;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
|
|
6
6
|
"names": ["linear", "useRaf"]
|
|
7
7
|
}
|
package/utils/tween.js
CHANGED
|
@@ -4,7 +4,7 @@ import { isDefined, isArray } from "./is.js";
|
|
|
4
4
|
import { noop, noopValue as linear } from "./noop.js";
|
|
5
5
|
import useRaf from "../services/raf.js";
|
|
6
6
|
let id = 0;
|
|
7
|
-
const PROGRESS_PRECISION =
|
|
7
|
+
const PROGRESS_PRECISION = 0.01;
|
|
8
8
|
function normalizeEase(ease) {
|
|
9
9
|
if (!isDefined(ease)) {
|
|
10
10
|
return linear;
|
package/utils/tween.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../packages/js-toolkit/utils/tween.js"],
|
|
4
|
-
"sourcesContent": ["import { cubicBezier } from '@motionone/easing';\nimport { lerp, map, clamp01 } from './math/index.js';\nimport { isDefined, isArray } from './is.js';\nimport { noop, noopValue as linear } from './noop.js';\nimport useRaf from '../services/raf.js';\n\nlet id = 0;\nconst PROGRESS_PRECISION = 0.
|
|
4
|
+
"sourcesContent": ["import { cubicBezier } from '@motionone/easing';\nimport { lerp, map, clamp01 } from './math/index.js';\nimport { isDefined, isArray } from './is.js';\nimport { noop, noopValue as linear } from './noop.js';\nimport useRaf from '../services/raf.js';\n\nlet id = 0;\nconst PROGRESS_PRECISION = 0.01;\n\n/**\n * @typedef {[number, number, number, number]} BezierCurve\n * @typedef {{\n * duration?: number;\n * easing?: import('./math/createEases.js').EasingFunction|BezierCurve;\n * onStart?: () => void;\n * onProgress?: (progress: number, easedProgress: number) => void;\n * onFinish?: (progress: number, easedProgress: number) => void;\n * }} TweenOptions\n */\n\n/**\n * Normalize a easing function with default fallbacks.\n * @param {((p:number) => number)|[number,number,number,number]} ease\n * @returns {(p:number) => number}\n */\nexport function normalizeEase(ease) {\n if (!isDefined(ease)) {\n return linear;\n }\n\n if (isArray(ease)) {\n return cubicBezier(...ease);\n }\n\n return ease;\n}\n\n/**\n * Tween from 0 to 1.\n * @param {(progress:number)=>any} callback\n * @param {TweenOptions} [options]\n * @returns {any}\n */\nexport function tween(callback, options = {}) {\n const raf = useRaf();\n\n let progressValue = 0;\n let easedProgress = 0;\n\n const ease = normalizeEase(options.easing);\n let duration = options.duration ?? 1;\n duration *= 1000;\n\n let startTime = performance.now();\n let endTime = startTime + duration;\n\n const key = `tw-${id}`;\n id += 1;\n\n const { onStart = noop, onProgress = noop, onFinish = noop } = options;\n let isRunning = false;\n\n /**\n * Pause the animation.\n *\n * @returns {void}\n */\n function pause() {\n isRunning = false;\n raf.remove(key);\n }\n\n /**\n * Set the progress value.\n *\n * @param {number} newProgress The new progress value.\n * @returns {number}\n */\n function progress(newProgress) {\n if (typeof newProgress === 'undefined') {\n return easedProgress;\n }\n\n progressValue = newProgress;\n easedProgress = ease(progressValue);\n\n // Stop when reaching precision\n if (Math.abs(1 - easedProgress) < PROGRESS_PRECISION) {\n progressValue = 1;\n easedProgress = 1;\n }\n\n callback(easedProgress);\n onProgress(progressValue, easedProgress);\n\n if (easedProgress === 1) {\n pause();\n requestAnimationFrame(() => onFinish(progressValue, easedProgress));\n }\n\n return progressValue;\n }\n\n /**\n * Loop for rendering the animation.\n *\n * @param {Object} props\n * @param {number} props.time\n * @returns {void}\n */\n function tick(props) {\n if (!isRunning) {\n raf.remove(key);\n return;\n }\n\n progress(clamp01(map(props.time, startTime, endTime, 0, 1)));\n }\n\n /**\n * Play the animation.\n *\n * @returns {void}\n */\n function start() {\n onStart();\n startTime = performance.now();\n endTime = startTime + duration;\n progressValue = 0;\n easedProgress = 0;\n isRunning = true;\n\n raf.add(key, tick);\n }\n\n /**\n * Play a paused animation.\n * @returns {void}\n */\n function play() {\n if (isRunning) {\n return;\n }\n\n startTime = performance.now() - lerp(0, duration, progressValue);\n endTime = startTime + duration;\n isRunning = true;\n\n raf.add(key, tick);\n }\n\n return {\n start,\n finish: () => progress(1),\n pause,\n play,\n progress,\n };\n}\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,mBAAmB;AAC5B,SAAS,MAAM,KAAK,eAAe;AACnC,SAAS,WAAW,eAAe;AACnC,SAAS,MAAM,aAAa,cAAc;AAC1C,OAAO,YAAY;AAEnB,IAAI,KAAK;AACT,MAAM,qBAAqB;AAkBpB,SAAS,cAAc,MAAM;AAClC,MAAI,CAAC,UAAU,IAAI,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,IAAI,GAAG;AACjB,WAAO,YAAY,GAAG,IAAI;AAAA,EAC5B;AAEA,SAAO;AACT;AAQO,SAAS,MAAM,UAAU,UAAU,CAAC,GAAG;AAC5C,QAAM,MAAM,OAAO;AAEnB,MAAI,gBAAgB;AACpB,MAAI,gBAAgB;AAEpB,QAAM,OAAO,cAAc,QAAQ,MAAM;AACzC,MAAI,WAAW,QAAQ,YAAY;AACnC,cAAY;AAEZ,MAAI,YAAY,YAAY,IAAI;AAChC,MAAI,UAAU,YAAY;AAE1B,QAAM,MAAM,MAAM;AAClB,QAAM;AAEN,QAAM,EAAE,UAAU,MAAM,aAAa,MAAM,WAAW,KAAK,IAAI;AAC/D,MAAI,YAAY;AAOhB,WAAS,QAAQ;AACf,gBAAY;AACZ,QAAI,OAAO,GAAG;AAAA,EAChB;AAQA,WAAS,SAAS,aAAa;AAC7B,QAAI,OAAO,gBAAgB,aAAa;AACtC,aAAO;AAAA,IACT;AAEA,oBAAgB;AAChB,oBAAgB,KAAK,aAAa;AAGlC,QAAI,KAAK,IAAI,IAAI,aAAa,IAAI,oBAAoB;AACpD,sBAAgB;AAChB,sBAAgB;AAAA,IAClB;AAEA,aAAS,aAAa;AACtB,eAAW,eAAe,aAAa;AAEvC,QAAI,kBAAkB,GAAG;AACvB,YAAM;AACN,4BAAsB,MAAM,SAAS,eAAe,aAAa,CAAC;AAAA,IACpE;AAEA,WAAO;AAAA,EACT;AASA,WAAS,KAAK,OAAO;AACnB,QAAI,CAAC,WAAW;AACd,UAAI,OAAO,GAAG;AACd;AAAA,IACF;AAEA,aAAS,QAAQ,IAAI,MAAM,MAAM,WAAW,SAAS,GAAG,CAAC,CAAC,CAAC;AAAA,EAC7D;AAOA,WAAS,QAAQ;AACf,YAAQ;AACR,gBAAY,YAAY,IAAI;AAC5B,cAAU,YAAY;AACtB,oBAAgB;AAChB,oBAAgB;AAChB,gBAAY;AAEZ,QAAI,IAAI,KAAK,IAAI;AAAA,EACnB;AAMA,WAAS,OAAO;AACd,QAAI,WAAW;AACb;AAAA,IACF;AAEA,gBAAY,YAAY,IAAI,IAAI,KAAK,GAAG,UAAU,aAAa;AAC/D,cAAU,YAAY;AACtB,gBAAY;AAEZ,QAAI,IAAI,KAAK,IAAI;AAAA,EACnB;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,MAAM,SAAS,CAAC;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|