@studiometa/js-toolkit 3.0.5 → 3.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studiometa/js-toolkit",
3
- "version": "3.0.5",
3
+ "version": "3.1.1",
4
4
  "description": "A set of useful little bits of JavaScript to boost your project! 🚀",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -2,6 +2,7 @@ import type { ServiceInterface } from './AbstractService.js';
2
2
  import { AbstractService } from './AbstractService.js';
3
3
  export interface RafServiceProps {
4
4
  time: DOMHighResTimeStamp;
5
+ delta: number;
5
6
  }
6
7
  export type RafServiceInterface = ServiceInterface<RafServiceProps>;
7
8
  export declare class RafService extends AbstractService<RafServiceProps> {
@@ -11,7 +11,8 @@ class RafService extends AbstractService {
11
11
  */
12
12
  scheduler = domScheduler;
13
13
  props = {
14
- time: performance.now()
14
+ time: performance.now(),
15
+ delta: 0
15
16
  };
16
17
  trigger(props) {
17
18
  for (const callback of this.callbacks.values()) {
@@ -26,7 +27,9 @@ class RafService extends AbstractService {
26
27
  }
27
28
  }
28
29
  loop() {
29
- this.props.time = performance.now();
30
+ const time = performance.now();
31
+ this.props.delta = time - this.props.time;
32
+ this.props.time = time;
30
33
  this.trigger(this.props);
31
34
  if (!this.isTicking) {
32
35
  return;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/services/RafService.ts"],
4
- "sourcesContent": ["import type { ServiceInterface } from './AbstractService.js';\nimport { AbstractService } from './AbstractService.js';\nimport { domScheduler } 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 /**\n * @private\n */\n isTicking = false;\n\n /**\n * @private\n */\n scheduler = domScheduler;\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.read(() => {\n const render = callback(props) as (() => unknown) | void;\n if (isFunction(render)) {\n this.scheduler.write(() => {\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\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;AAAA;AAAA;AAAA,EAI/D,YAAY;AAAA;AAAA;AAAA;AAAA,EAKZ,YAAY;AAAA,EAEZ,QAAyB;AAAA,IACvB,MAAM,YAAY,IAAI;AAAA,EACxB;AAAA,EAEA,QAAQ,OAAwB;AAC9B,eAAW,YAAY,KAAK,UAAU,OAAO,GAAG;AAC9C,WAAK,UAAU,KAAK,MAAM;AACxB,cAAM,SAAS,SAAS,KAAK;AAC7B,YAAI,WAAW,MAAM,GAAG;AACtB,eAAK,UAAU,MAAM,MAAM;AAEzB,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,EAEA,OAAO;AACL,SAAK,YAAY;AAAA,EACnB;AACF;AAKO,SAAS,SAA8B;AAC5C,SAAO,WAAW,YAAY;AAChC;",
4
+ "sourcesContent": ["import type { ServiceInterface } from './AbstractService.js';\nimport { AbstractService } from './AbstractService.js';\nimport { domScheduler } from '../utils/scheduler.js';\nimport { isFunction } from '../utils/is.js';\n\nexport interface RafServiceProps {\n time: DOMHighResTimeStamp;\n delta: number;\n}\n\nexport type RafServiceInterface = ServiceInterface<RafServiceProps>;\n\nexport class RafService extends AbstractService<RafServiceProps> {\n /**\n * @private\n */\n isTicking = false;\n\n /**\n * @private\n */\n scheduler = domScheduler;\n\n props: RafServiceProps = {\n time: performance.now(),\n delta: 0,\n };\n\n trigger(props: RafServiceProps) {\n for (const callback of this.callbacks.values()) {\n this.scheduler.read(() => {\n const render = callback(props) as (() => unknown) | void;\n if (isFunction(render)) {\n this.scheduler.write(() => {\n // @ts-ignore\n render(props);\n });\n }\n });\n }\n }\n\n loop() {\n const time = performance.now();\n this.props.delta = time - this.props.time;\n this.props.time = time;\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\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;AASpB,MAAM,mBAAmB,gBAAiC;AAAA;AAAA;AAAA;AAAA,EAI/D,YAAY;AAAA;AAAA;AAAA;AAAA,EAKZ,YAAY;AAAA,EAEZ,QAAyB;AAAA,IACvB,MAAM,YAAY,IAAI;AAAA,IACtB,OAAO;AAAA,EACT;AAAA,EAEA,QAAQ,OAAwB;AAC9B,eAAW,YAAY,KAAK,UAAU,OAAO,GAAG;AAC9C,WAAK,UAAU,KAAK,MAAM;AACxB,cAAM,SAAS,SAAS,KAAK;AAC7B,YAAI,WAAW,MAAM,GAAG;AACtB,eAAK,UAAU,MAAM,MAAM;AAEzB,mBAAO,KAAK;AAAA,UACd,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,OAAO;AACL,UAAM,OAAO,YAAY,IAAI;AAC7B,SAAK,MAAM,QAAQ,OAAO,KAAK,MAAM;AACrC,SAAK,MAAM,OAAO;AAClB,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,EAEA,OAAO;AACL,SAAK,YAAY;AAAA,EACnB;AACF;AAKO,SAAS,SAA8B;AAC5C,SAAO,WAAW,YAAY;AAChC;",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"root":["../packages/global.d.ts","../packages/js-toolkit/index.ts","../packages/js-toolkit/base/base.ts","../packages/js-toolkit/base/features.ts","../packages/js-toolkit/base/index.ts","../packages/js-toolkit/base/types.ts","../packages/js-toolkit/base/utils.ts","../packages/js-toolkit/base/managers/abstractmanager.ts","../packages/js-toolkit/base/managers/childrenmanager.ts","../packages/js-toolkit/base/managers/eventsmanager.ts","../packages/js-toolkit/base/managers/optionsmanager.ts","../packages/js-toolkit/base/managers/refsmanager.ts","../packages/js-toolkit/base/managers/responsiveoptionsmanager.ts","../packages/js-toolkit/base/managers/servicesmanager.ts","../packages/js-toolkit/base/managers/index.ts","../packages/js-toolkit/decorators/index.ts","../packages/js-toolkit/decorators/withbreakpointmanager.ts","../packages/js-toolkit/decorators/withbreakpointobserver.ts","../packages/js-toolkit/decorators/withdrag.ts","../packages/js-toolkit/decorators/withextraconfig.ts","../packages/js-toolkit/decorators/withfreezedoptions.ts","../packages/js-toolkit/decorators/withintersectionobserver.ts","../packages/js-toolkit/decorators/withmountonmediaquery.ts","../packages/js-toolkit/decorators/withmountwheninview.ts","../packages/js-toolkit/decorators/withmountwhenprefersmotion.ts","../packages/js-toolkit/decorators/withmutation.ts","../packages/js-toolkit/decorators/withname.ts","../packages/js-toolkit/decorators/withrelativepointer.ts","../packages/js-toolkit/decorators/withresponsiveoptions.ts","../packages/js-toolkit/decorators/withscrolledinview/index.ts","../packages/js-toolkit/decorators/withscrolledinview/types.ts","../packages/js-toolkit/decorators/withscrolledinview/utils.ts","../packages/js-toolkit/decorators/withscrolledinview/withscrolledinview.ts","../packages/js-toolkit/helpers/createapp.ts","../packages/js-toolkit/helpers/getclosestparent.ts","../packages/js-toolkit/helpers/getdirectchildren.ts","../packages/js-toolkit/helpers/getinstancefromelement.ts","../packages/js-toolkit/helpers/importoninteraction.ts","../packages/js-toolkit/helpers/importonmediaquery.ts","../packages/js-toolkit/helpers/importwhenidle.ts","../packages/js-toolkit/helpers/importwhenprefersmotion.ts","../packages/js-toolkit/helpers/importwhenvisible.ts","../packages/js-toolkit/helpers/index.ts","../packages/js-toolkit/helpers/utils.ts","../packages/js-toolkit/services/abstractservice.ts","../packages/js-toolkit/services/dragservice.ts","../packages/js-toolkit/services/keyservice.ts","../packages/js-toolkit/services/loadservice.ts","../packages/js-toolkit/services/mutationservice.ts","../packages/js-toolkit/services/pointerservice.ts","../packages/js-toolkit/services/rafservice.ts","../packages/js-toolkit/services/resizeservice.ts","../packages/js-toolkit/services/scrollservice.ts","../packages/js-toolkit/services/index.ts","../packages/js-toolkit/services/utils.ts","../packages/js-toolkit/utils/queue.ts","../packages/js-toolkit/utils/smartqueue.ts","../packages/js-toolkit/utils/cache.ts","../packages/js-toolkit/utils/debounce.ts","../packages/js-toolkit/utils/getcomponentresolver.ts","../packages/js-toolkit/utils/has.ts","../packages/js-toolkit/utils/history.ts","../packages/js-toolkit/utils/index.ts","../packages/js-toolkit/utils/is.ts","../packages/js-toolkit/utils/keycodes.ts","../packages/js-toolkit/utils/loadelement.ts","../packages/js-toolkit/utils/memo.ts","../packages/js-toolkit/utils/memoize.ts","../packages/js-toolkit/utils/nextframe.ts","../packages/js-toolkit/utils/nextmicrotask.ts","../packages/js-toolkit/utils/nexttick.ts","../packages/js-toolkit/utils/noop.ts","../packages/js-toolkit/utils/random.ts","../packages/js-toolkit/utils/scheduler.ts","../packages/js-toolkit/utils/scrollto.ts","../packages/js-toolkit/utils/throttle.ts","../packages/js-toolkit/utils/trapfocus.ts","../packages/js-toolkit/utils/tween.ts","../packages/js-toolkit/utils/wait.ts","../packages/js-toolkit/utils/collide/boundingrecttocircle.ts","../packages/js-toolkit/utils/collide/collidecirclecircle.ts","../packages/js-toolkit/utils/collide/collidecirclerect.ts","../packages/js-toolkit/utils/collide/collidepointcircle.ts","../packages/js-toolkit/utils/collide/collidepointrect.ts","../packages/js-toolkit/utils/collide/colliderectrect.ts","../packages/js-toolkit/utils/collide/index.ts","../packages/js-toolkit/utils/css/animate.ts","../packages/js-toolkit/utils/css/classes.ts","../packages/js-toolkit/utils/css/getoffsetsizes.ts","../packages/js-toolkit/utils/css/index.ts","../packages/js-toolkit/utils/css/matrix.ts","../packages/js-toolkit/utils/css/styles.ts","../packages/js-toolkit/utils/css/transform.ts","../packages/js-toolkit/utils/css/transition.ts","../packages/js-toolkit/utils/css/utils.ts","../packages/js-toolkit/utils/dom/ancestors.ts","../packages/js-toolkit/utils/dom/createelement.ts","../packages/js-toolkit/utils/dom/index.ts","../packages/js-toolkit/utils/math/clamp.ts","../packages/js-toolkit/utils/math/clamp01.ts","../packages/js-toolkit/utils/math/createeases.ts","../packages/js-toolkit/utils/math/createrange.ts","../packages/js-toolkit/utils/math/damp.ts","../packages/js-toolkit/utils/math/ease.ts","../packages/js-toolkit/utils/math/index.ts","../packages/js-toolkit/utils/math/inertiafinalvalue.ts","../packages/js-toolkit/utils/math/lerp.ts","../packages/js-toolkit/utils/math/map.ts","../packages/js-toolkit/utils/math/mean.ts","../packages/js-toolkit/utils/math/round.ts","../packages/js-toolkit/utils/object/getallproperties.ts","../packages/js-toolkit/utils/string/changecase.ts","../packages/js-toolkit/utils/string/endswith.ts","../packages/js-toolkit/utils/string/index.ts","../packages/js-toolkit/utils/string/startswith.ts","../packages/js-toolkit/utils/string/withleadingcharacters.ts","../packages/js-toolkit/utils/string/withleadingslash.ts","../packages/js-toolkit/utils/string/withtrailingcharacters.ts","../packages/js-toolkit/utils/string/withtrailingslash.ts","../packages/js-toolkit/utils/string/withoutleadingcharacters.ts","../packages/js-toolkit/utils/string/withoutleadingcharactersrecursive.ts","../packages/js-toolkit/utils/string/withoutleadingslash.ts","../packages/js-toolkit/utils/string/withouttrailingcharacters.ts","../packages/js-toolkit/utils/string/withouttrailingcharactersrecursive.ts","../packages/js-toolkit/utils/string/withouttrailingslash.ts"],"version":"5.8.3"}
1
+ {"root":["../packages/global.d.ts","../packages/js-toolkit/index.ts","../packages/js-toolkit/base/base.ts","../packages/js-toolkit/base/features.ts","../packages/js-toolkit/base/index.ts","../packages/js-toolkit/base/types.ts","../packages/js-toolkit/base/utils.ts","../packages/js-toolkit/base/managers/abstractmanager.ts","../packages/js-toolkit/base/managers/childrenmanager.ts","../packages/js-toolkit/base/managers/eventsmanager.ts","../packages/js-toolkit/base/managers/optionsmanager.ts","../packages/js-toolkit/base/managers/refsmanager.ts","../packages/js-toolkit/base/managers/responsiveoptionsmanager.ts","../packages/js-toolkit/base/managers/servicesmanager.ts","../packages/js-toolkit/base/managers/index.ts","../packages/js-toolkit/decorators/index.ts","../packages/js-toolkit/decorators/withbreakpointmanager.ts","../packages/js-toolkit/decorators/withbreakpointobserver.ts","../packages/js-toolkit/decorators/withdrag.ts","../packages/js-toolkit/decorators/withextraconfig.ts","../packages/js-toolkit/decorators/withfreezedoptions.ts","../packages/js-toolkit/decorators/withintersectionobserver.ts","../packages/js-toolkit/decorators/withmountonmediaquery.ts","../packages/js-toolkit/decorators/withmountwheninview.ts","../packages/js-toolkit/decorators/withmountwhenprefersmotion.ts","../packages/js-toolkit/decorators/withmutation.ts","../packages/js-toolkit/decorators/withname.ts","../packages/js-toolkit/decorators/withrelativepointer.ts","../packages/js-toolkit/decorators/withresponsiveoptions.ts","../packages/js-toolkit/decorators/withscrolledinview/index.ts","../packages/js-toolkit/decorators/withscrolledinview/types.ts","../packages/js-toolkit/decorators/withscrolledinview/utils.ts","../packages/js-toolkit/decorators/withscrolledinview/withscrolledinview.ts","../packages/js-toolkit/helpers/createapp.ts","../packages/js-toolkit/helpers/getclosestparent.ts","../packages/js-toolkit/helpers/getdirectchildren.ts","../packages/js-toolkit/helpers/getinstancefromelement.ts","../packages/js-toolkit/helpers/importoninteraction.ts","../packages/js-toolkit/helpers/importonmediaquery.ts","../packages/js-toolkit/helpers/importwhenidle.ts","../packages/js-toolkit/helpers/importwhenprefersmotion.ts","../packages/js-toolkit/helpers/importwhenvisible.ts","../packages/js-toolkit/helpers/index.ts","../packages/js-toolkit/helpers/utils.ts","../packages/js-toolkit/services/abstractservice.ts","../packages/js-toolkit/services/dragservice.ts","../packages/js-toolkit/services/keyservice.ts","../packages/js-toolkit/services/loadservice.ts","../packages/js-toolkit/services/mutationservice.ts","../packages/js-toolkit/services/pointerservice.ts","../packages/js-toolkit/services/rafservice.ts","../packages/js-toolkit/services/resizeservice.ts","../packages/js-toolkit/services/scrollservice.ts","../packages/js-toolkit/services/index.ts","../packages/js-toolkit/services/utils.ts","../packages/js-toolkit/utils/queue.ts","../packages/js-toolkit/utils/smartqueue.ts","../packages/js-toolkit/utils/cache.ts","../packages/js-toolkit/utils/debounce.ts","../packages/js-toolkit/utils/getcomponentresolver.ts","../packages/js-toolkit/utils/has.ts","../packages/js-toolkit/utils/history.ts","../packages/js-toolkit/utils/index.ts","../packages/js-toolkit/utils/is.ts","../packages/js-toolkit/utils/keycodes.ts","../packages/js-toolkit/utils/loadelement.ts","../packages/js-toolkit/utils/memo.ts","../packages/js-toolkit/utils/memoize.ts","../packages/js-toolkit/utils/nextframe.ts","../packages/js-toolkit/utils/nextmicrotask.ts","../packages/js-toolkit/utils/nexttick.ts","../packages/js-toolkit/utils/noop.ts","../packages/js-toolkit/utils/random.ts","../packages/js-toolkit/utils/scheduler.ts","../packages/js-toolkit/utils/scrollto.ts","../packages/js-toolkit/utils/throttle.ts","../packages/js-toolkit/utils/trapfocus.ts","../packages/js-toolkit/utils/tween.ts","../packages/js-toolkit/utils/wait.ts","../packages/js-toolkit/utils/collide/boundingrecttocircle.ts","../packages/js-toolkit/utils/collide/collidecirclecircle.ts","../packages/js-toolkit/utils/collide/collidecirclerect.ts","../packages/js-toolkit/utils/collide/collidepointcircle.ts","../packages/js-toolkit/utils/collide/collidepointrect.ts","../packages/js-toolkit/utils/collide/colliderectrect.ts","../packages/js-toolkit/utils/collide/index.ts","../packages/js-toolkit/utils/css/animate.ts","../packages/js-toolkit/utils/css/classes.ts","../packages/js-toolkit/utils/css/getoffsetsizes.ts","../packages/js-toolkit/utils/css/index.ts","../packages/js-toolkit/utils/css/matrix.ts","../packages/js-toolkit/utils/css/styles.ts","../packages/js-toolkit/utils/css/transform.ts","../packages/js-toolkit/utils/css/transition.ts","../packages/js-toolkit/utils/css/utils.ts","../packages/js-toolkit/utils/dom/ancestors.ts","../packages/js-toolkit/utils/dom/createelement.ts","../packages/js-toolkit/utils/dom/index.ts","../packages/js-toolkit/utils/math/clamp.ts","../packages/js-toolkit/utils/math/clamp01.ts","../packages/js-toolkit/utils/math/createeases.ts","../packages/js-toolkit/utils/math/createrange.ts","../packages/js-toolkit/utils/math/damp.ts","../packages/js-toolkit/utils/math/ease.ts","../packages/js-toolkit/utils/math/index.ts","../packages/js-toolkit/utils/math/inertiafinalvalue.ts","../packages/js-toolkit/utils/math/lerp.ts","../packages/js-toolkit/utils/math/map.ts","../packages/js-toolkit/utils/math/mean.ts","../packages/js-toolkit/utils/math/round.ts","../packages/js-toolkit/utils/math/smoothto.ts","../packages/js-toolkit/utils/math/spring.ts","../packages/js-toolkit/utils/math/wrap.ts","../packages/js-toolkit/utils/object/getallproperties.ts","../packages/js-toolkit/utils/string/changecase.ts","../packages/js-toolkit/utils/string/endswith.ts","../packages/js-toolkit/utils/string/index.ts","../packages/js-toolkit/utils/string/startswith.ts","../packages/js-toolkit/utils/string/withleadingcharacters.ts","../packages/js-toolkit/utils/string/withleadingslash.ts","../packages/js-toolkit/utils/string/withtrailingcharacters.ts","../packages/js-toolkit/utils/string/withtrailingslash.ts","../packages/js-toolkit/utils/string/withoutleadingcharacters.ts","../packages/js-toolkit/utils/string/withoutleadingcharactersrecursive.ts","../packages/js-toolkit/utils/string/withoutleadingslash.ts","../packages/js-toolkit/utils/string/withouttrailingcharacters.ts","../packages/js-toolkit/utils/string/withouttrailingcharactersrecursive.ts","../packages/js-toolkit/utils/string/withouttrailingslash.ts"],"version":"5.9.2"}
@@ -17,6 +17,7 @@ const TRANSFORM_PROPS = [
17
17
  "skewY"
18
18
  ];
19
19
  function transform(elementOrElements, props) {
20
+ if (!elementOrElements) return;
20
21
  let value = "";
21
22
  if (isDefined(props.x) || isDefined(props.y) || isDefined(props.z)) {
22
23
  value += `translate3d(${props.x ?? 0}px, ${props.y ?? 0}px, ${props.z ?? 0}px) `;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/js-toolkit/utils/css/transform.ts"],
4
- "sourcesContent": ["import { isDefined } from '../is.js';\n// eslint-disable-next-line import/extensions\nimport { eachElements } from './utils.js';\n\nexport type TransformProps = Partial<{\n x: number;\n y: number;\n z: number;\n rotate: number;\n rotateX: number;\n rotateY: number;\n rotateZ: number;\n scale: number;\n scaleX: number;\n scaleY: number;\n scaleZ: number;\n skew: number;\n skewX: number;\n skewY: number;\n}>;\n\nexport const TRANSFORM_PROPS = [\n 'x',\n 'y',\n 'z',\n 'rotate',\n 'rotateX',\n 'rotateY',\n 'rotateZ',\n 'scale',\n 'scaleX',\n 'scaleY',\n 'scaleZ',\n 'skew',\n 'skewX',\n 'skewY',\n];\n\n/**\n * Generate a CSS transform.\n */\nexport function transform(\n elementOrElements: HTMLElement | HTMLElement[] | NodeListOf<HTMLElement>,\n props: TransformProps,\n): string {\n let value = '';\n\n if (isDefined(props.x) || isDefined(props.y) || isDefined(props.z)) {\n value += `translate3d(${props.x ?? 0}px, ${props.y ?? 0}px, ${props.z ?? 0}px) `;\n }\n\n if (isDefined(props.rotate)) {\n value += `rotate(${props.rotate}deg) `;\n } else {\n if (isDefined(props.rotateX)) {\n value += `rotateX(${props.rotateX}deg) `;\n }\n\n if (isDefined(props.rotateY)) {\n value += `rotateY(${props.rotateY}deg) `;\n }\n\n if (isDefined(props.rotateZ)) {\n value += `rotateZ(${props.rotateZ}deg) `;\n }\n }\n\n if (isDefined(props.scale)) {\n value += `scale(${props.scale}) `;\n } else {\n if (isDefined(props.scaleX)) {\n value += `scaleX(${props.scaleX}) `;\n }\n\n if (isDefined(props.scaleY)) {\n value += `scaleY(${props.scaleY}) `;\n }\n\n if (isDefined(props.scaleZ)) {\n value += `scaleZ(${props.scaleZ}) `;\n }\n }\n\n if (isDefined(props.skew)) {\n value += `skew(${props.skew}deg) `;\n } else {\n if (isDefined(props.skewX)) {\n value += `skewX(${props.skewX}deg) `;\n }\n\n if (isDefined(props.skewY)) {\n value += `skewY(${props.skewY}deg) `;\n }\n }\n\n eachElements(elementOrElements, (element) => {\n element.style.transform = value;\n });\n return value;\n}\n"],
5
- "mappings": "AAAA,SAAS,iBAAiB;AAE1B,SAAS,oBAAoB;AAmBtB,MAAM,kBAAkB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKO,SAAS,UACd,mBACA,OACQ;AACR,MAAI,QAAQ;AAEZ,MAAI,UAAU,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,GAAG;AAClE,aAAS,eAAe,MAAM,KAAK,CAAC,OAAO,MAAM,KAAK,CAAC,OAAO,MAAM,KAAK,CAAC;AAAA,EAC5E;AAEA,MAAI,UAAU,MAAM,MAAM,GAAG;AAC3B,aAAS,UAAU,MAAM,MAAM;AAAA,EACjC,OAAO;AACL,QAAI,UAAU,MAAM,OAAO,GAAG;AAC5B,eAAS,WAAW,MAAM,OAAO;AAAA,IACnC;AAEA,QAAI,UAAU,MAAM,OAAO,GAAG;AAC5B,eAAS,WAAW,MAAM,OAAO;AAAA,IACnC;AAEA,QAAI,UAAU,MAAM,OAAO,GAAG;AAC5B,eAAS,WAAW,MAAM,OAAO;AAAA,IACnC;AAAA,EACF;AAEA,MAAI,UAAU,MAAM,KAAK,GAAG;AAC1B,aAAS,SAAS,MAAM,KAAK;AAAA,EAC/B,OAAO;AACL,QAAI,UAAU,MAAM,MAAM,GAAG;AAC3B,eAAS,UAAU,MAAM,MAAM;AAAA,IACjC;AAEA,QAAI,UAAU,MAAM,MAAM,GAAG;AAC3B,eAAS,UAAU,MAAM,MAAM;AAAA,IACjC;AAEA,QAAI,UAAU,MAAM,MAAM,GAAG;AAC3B,eAAS,UAAU,MAAM,MAAM;AAAA,IACjC;AAAA,EACF;AAEA,MAAI,UAAU,MAAM,IAAI,GAAG;AACzB,aAAS,QAAQ,MAAM,IAAI;AAAA,EAC7B,OAAO;AACL,QAAI,UAAU,MAAM,KAAK,GAAG;AAC1B,eAAS,SAAS,MAAM,KAAK;AAAA,IAC/B;AAEA,QAAI,UAAU,MAAM,KAAK,GAAG;AAC1B,eAAS,SAAS,MAAM,KAAK;AAAA,IAC/B;AAAA,EACF;AAEA,eAAa,mBAAmB,CAAC,YAAY;AAC3C,YAAQ,MAAM,YAAY;AAAA,EAC5B,CAAC;AACD,SAAO;AACT;",
4
+ "sourcesContent": ["import { isDefined } from '../is.js';\n// eslint-disable-next-line import/extensions\nimport { eachElements } from './utils.js';\n\nexport type TransformProps = Partial<{\n x: number;\n y: number;\n z: number;\n rotate: number;\n rotateX: number;\n rotateY: number;\n rotateZ: number;\n scale: number;\n scaleX: number;\n scaleY: number;\n scaleZ: number;\n skew: number;\n skewX: number;\n skewY: number;\n}>;\n\nexport const TRANSFORM_PROPS = [\n 'x',\n 'y',\n 'z',\n 'rotate',\n 'rotateX',\n 'rotateY',\n 'rotateZ',\n 'scale',\n 'scaleX',\n 'scaleY',\n 'scaleZ',\n 'skew',\n 'skewX',\n 'skewY',\n];\n\n/**\n * Generate a CSS transform.\n */\nexport function transform(\n elementOrElements: HTMLElement | HTMLElement[] | NodeListOf<HTMLElement>,\n props: TransformProps,\n): string {\n if (!elementOrElements) return\n\n let value = '';\n\n if (isDefined(props.x) || isDefined(props.y) || isDefined(props.z)) {\n value += `translate3d(${props.x ?? 0}px, ${props.y ?? 0}px, ${props.z ?? 0}px) `;\n }\n\n if (isDefined(props.rotate)) {\n value += `rotate(${props.rotate}deg) `;\n } else {\n if (isDefined(props.rotateX)) {\n value += `rotateX(${props.rotateX}deg) `;\n }\n\n if (isDefined(props.rotateY)) {\n value += `rotateY(${props.rotateY}deg) `;\n }\n\n if (isDefined(props.rotateZ)) {\n value += `rotateZ(${props.rotateZ}deg) `;\n }\n }\n\n if (isDefined(props.scale)) {\n value += `scale(${props.scale}) `;\n } else {\n if (isDefined(props.scaleX)) {\n value += `scaleX(${props.scaleX}) `;\n }\n\n if (isDefined(props.scaleY)) {\n value += `scaleY(${props.scaleY}) `;\n }\n\n if (isDefined(props.scaleZ)) {\n value += `scaleZ(${props.scaleZ}) `;\n }\n }\n\n if (isDefined(props.skew)) {\n value += `skew(${props.skew}deg) `;\n } else {\n if (isDefined(props.skewX)) {\n value += `skewX(${props.skewX}deg) `;\n }\n\n if (isDefined(props.skewY)) {\n value += `skewY(${props.skewY}deg) `;\n }\n }\n\n eachElements(elementOrElements, (element) => {\n element.style.transform = value;\n });\n return value;\n}\n"],
5
+ "mappings": "AAAA,SAAS,iBAAiB;AAE1B,SAAS,oBAAoB;AAmBtB,MAAM,kBAAkB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKO,SAAS,UACd,mBACA,OACQ;AACR,MAAI,CAAC,kBAAmB;AAExB,MAAI,QAAQ;AAEZ,MAAI,UAAU,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,GAAG;AAClE,aAAS,eAAe,MAAM,KAAK,CAAC,OAAO,MAAM,KAAK,CAAC,OAAO,MAAM,KAAK,CAAC;AAAA,EAC5E;AAEA,MAAI,UAAU,MAAM,MAAM,GAAG;AAC3B,aAAS,UAAU,MAAM,MAAM;AAAA,EACjC,OAAO;AACL,QAAI,UAAU,MAAM,OAAO,GAAG;AAC5B,eAAS,WAAW,MAAM,OAAO;AAAA,IACnC;AAEA,QAAI,UAAU,MAAM,OAAO,GAAG;AAC5B,eAAS,WAAW,MAAM,OAAO;AAAA,IACnC;AAEA,QAAI,UAAU,MAAM,OAAO,GAAG;AAC5B,eAAS,WAAW,MAAM,OAAO;AAAA,IACnC;AAAA,EACF;AAEA,MAAI,UAAU,MAAM,KAAK,GAAG;AAC1B,aAAS,SAAS,MAAM,KAAK;AAAA,EAC/B,OAAO;AACL,QAAI,UAAU,MAAM,MAAM,GAAG;AAC3B,eAAS,UAAU,MAAM,MAAM;AAAA,IACjC;AAEA,QAAI,UAAU,MAAM,MAAM,GAAG;AAC3B,eAAS,UAAU,MAAM,MAAM;AAAA,IACjC;AAEA,QAAI,UAAU,MAAM,MAAM,GAAG;AAC3B,eAAS,UAAU,MAAM,MAAM;AAAA,IACjC;AAAA,EACF;AAEA,MAAI,UAAU,MAAM,IAAI,GAAG;AACzB,aAAS,QAAQ,MAAM,IAAI;AAAA,EAC7B,OAAO;AACL,QAAI,UAAU,MAAM,KAAK,GAAG;AAC1B,eAAS,SAAS,MAAM,KAAK;AAAA,IAC/B;AAEA,QAAI,UAAU,MAAM,KAAK,GAAG;AAC1B,eAAS,SAAS,MAAM,KAAK;AAAA,IAC/B;AAAA,EACF;AAEA,eAAa,mBAAmB,CAAC,YAAY;AAC3C,YAAQ,MAAM,YAAY;AAAA,EAC5B,CAAC;AACD,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -5,8 +5,11 @@ export { createRange } from './createRange.js';
5
5
  export { clamp } from './clamp.js';
6
6
  export { clamp01 } from './clamp01.js';
7
7
  export { damp } from './damp.js';
8
+ export { spring } from './spring.js';
8
9
  export { inertiaFinalValue } from './inertiaFinalValue.js';
9
10
  export { lerp } from './lerp.js';
10
11
  export { map } from './map.js';
11
12
  export { round } from './round.js';
12
13
  export { mean } from './mean.js';
14
+ export { smoothTo } from './smoothTo.js';
15
+ export { wrap } from './wrap.js';
@@ -5,11 +5,14 @@ import { createRange } from "./createRange.js";
5
5
  import { clamp } from "./clamp.js";
6
6
  import { clamp01 } from "./clamp01.js";
7
7
  import { damp } from "./damp.js";
8
+ import { spring } from "./spring.js";
8
9
  import { inertiaFinalValue } from "./inertiaFinalValue.js";
9
10
  import { lerp } from "./lerp.js";
10
11
  import { map } from "./map.js";
11
12
  import { round } from "./round.js";
12
13
  import { mean } from "./mean.js";
14
+ import { smoothTo } from "./smoothTo.js";
15
+ import { wrap } from "./wrap.js";
13
16
  export {
14
17
  clamp,
15
18
  clamp01,
@@ -20,6 +23,9 @@ export {
20
23
  lerp,
21
24
  map,
22
25
  mean,
23
- round
26
+ round,
27
+ smoothTo,
28
+ spring,
29
+ wrap
24
30
  };
25
31
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../packages/js-toolkit/utils/math/index.ts"],
4
- "sourcesContent": ["export * as ease from './ease.js';\nexport * from './createEases.js';\nexport * from './ease.js';\nexport { createRange } from './createRange.js';\nexport { clamp } from './clamp.js';\nexport { clamp01 } from './clamp01.js';\nexport { damp } from './damp.js';\nexport { inertiaFinalValue } from './inertiaFinalValue.js';\nexport { lerp } from './lerp.js';\nexport { map } from './map.js';\nexport { round } from './round.js';\nexport { mean } from './mean.js';\n"],
5
- "mappings": "AAAA,YAAY,UAAU;AACtB,cAAc;AACd,cAAc;AACd,SAAS,mBAAmB;AAC5B,SAAS,aAAa;AACtB,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,SAAS,yBAAyB;AAClC,SAAS,YAAY;AACrB,SAAS,WAAW;AACpB,SAAS,aAAa;AACtB,SAAS,YAAY;",
4
+ "sourcesContent": ["export * as ease from './ease.js';\nexport * from './createEases.js';\nexport * from './ease.js';\nexport { createRange } from './createRange.js';\nexport { clamp } from './clamp.js';\nexport { clamp01 } from './clamp01.js';\nexport { damp } from './damp.js';\nexport { spring } from './spring.js';\nexport { inertiaFinalValue } from './inertiaFinalValue.js';\nexport { lerp } from './lerp.js';\nexport { map } from './map.js';\nexport { round } from './round.js';\nexport { mean } from './mean.js';\nexport { smoothTo } from './smoothTo.js';\nexport { wrap } from './wrap.js';\n"],
5
+ "mappings": "AAAA,YAAY,UAAU;AACtB,cAAc;AACd,cAAc;AACd,SAAS,mBAAmB;AAC5B,SAAS,aAAa;AACtB,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,SAAS,cAAc;AACvB,SAAS,yBAAyB;AAClC,SAAS,YAAY;AACrB,SAAS,WAAW;AACpB,SAAS,aAAa;AACtB,SAAS,YAAY;AACrB,SAAS,gBAAgB;AACzB,SAAS,YAAY;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,51 @@
1
+ export type SmoothToOptions = Partial<{
2
+ /**
3
+ * Damping factor, the smaller the smoother, defaults to 0.6.
4
+ */
5
+ damping: number;
6
+ /**
7
+ * Precision used to decide when the smoothing should end, defaults to 1 / 1e8.
8
+ */
9
+ precision: number;
10
+ /**
11
+ * Enable spring physics, defaults to `true` if one of `stiffness` or `mass` is set, defaults to `false` otherwise.
12
+ */
13
+ spring: boolean;
14
+ /**
15
+ * Stiffness factor for spring physics, the higher the stiffer, defaults to 0.1.
16
+ */
17
+ stiffness: number;
18
+ /**
19
+ * Mass factor when spring is enabled, the higher the heavier, defaults to 1.
20
+ */
21
+ mass: number;
22
+ }>;
23
+ /**
24
+ * Create a smoothing function that will smoothly tween between two values.
25
+ * @param {number} [start] The initial value.
26
+ * @param {SmoothToOptions} [options] Options for the transition.
27
+ * @see https://js-toolkit.studiometa.dev/utils/math/smoothTo.html
28
+ * @example
29
+ * ```js
30
+ * const x = smoothTo(0);
31
+ * x.subscribe((value) => console.log(value));
32
+ * x(100); // 0.1
33
+ * ```
34
+ */
35
+ export declare function smoothTo(start?: number, options?: SmoothToOptions): {
36
+ (newValue?: number): number;
37
+ /**
38
+ * Subscribe a callback to the value update.
39
+ */
40
+ subscribe: (fn: (value: number) => any) => () => boolean;
41
+ /**
42
+ * Unsubscribe a callback from the value update.
43
+ */
44
+ unsubscribe: (fn: (value: number) => any) => boolean;
45
+ raw(): number;
46
+ add(val: number): number;
47
+ damping(val?: number): number;
48
+ precision(val?: number): number;
49
+ stiffness(val?: number): number;
50
+ spring(val?: boolean): boolean;
51
+ };
@@ -0,0 +1,56 @@
1
+ import { damp } from "./damp.js";
2
+ import { spring } from "./spring.js";
3
+ import { isFunction, isDefined } from "../is.js";
4
+ function smoothTo(start = 0, options = {}) {
5
+ const fns = /* @__PURE__ */ new Set();
6
+ let damping = options.damping ?? 0.6;
7
+ let precision = options.precision ?? 1 / 1e8;
8
+ let stiffness = options.stiffness ?? 0.1;
9
+ let mass = options.mass ?? 1;
10
+ let isSpring = options.spring === true || isDefined(options.stiffness) || isDefined(options.mass);
11
+ let value = start;
12
+ let smoothed = start;
13
+ let velocity = 0;
14
+ function tick() {
15
+ if (isSpring) {
16
+ [smoothed, velocity] = spring(value, smoothed, velocity, stiffness, damping, mass, precision);
17
+ } else {
18
+ smoothed = damp(value, smoothed, damping, precision);
19
+ }
20
+ for (const fn of fns) {
21
+ fn(smoothed);
22
+ }
23
+ if (smoothed !== value) requestAnimationFrame(tick);
24
+ }
25
+ function subscribe(fn) {
26
+ if (isFunction(fn)) {
27
+ fns.add(fn);
28
+ }
29
+ return () => unsubscribe(fn);
30
+ }
31
+ function unsubscribe(fn) {
32
+ return fns.delete(fn);
33
+ }
34
+ function update(newValue) {
35
+ if (!isDefined(newValue)) {
36
+ return smoothed;
37
+ }
38
+ value = newValue;
39
+ tick();
40
+ return smoothed;
41
+ }
42
+ update.subscribe = subscribe;
43
+ update.unsubscribe = unsubscribe;
44
+ update.raw = () => value;
45
+ update.add = (val) => update(value + val);
46
+ update.damping = (val) => damping = val ?? damping;
47
+ update.precision = (val) => precision = val ?? precision;
48
+ update.stiffness = (val) => stiffness = val ?? stiffness;
49
+ update.spring = (val) => isSpring = val ?? isSpring;
50
+ update(start);
51
+ return update;
52
+ }
53
+ export {
54
+ smoothTo
55
+ };
56
+ //# sourceMappingURL=smoothTo.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../packages/js-toolkit/utils/math/smoothTo.ts"],
4
+ "sourcesContent": ["import { damp } from './damp.js';\nimport { spring } from './spring.js';\nimport { isFunction, isDefined } from '../is.js';\n\nexport type SmoothToOptions = Partial<{\n /**\n * Damping factor, the smaller the smoother, defaults to 0.6.\n */\n damping: number;\n /**\n * Precision used to decide when the smoothing should end, defaults to 1 / 1e8.\n */\n precision: number;\n /**\n * Enable spring physics, defaults to `true` if one of `stiffness` or `mass` is set, defaults to `false` otherwise.\n */\n spring: boolean;\n /**\n * Stiffness factor for spring physics, the higher the stiffer, defaults to 0.1.\n */\n stiffness: number;\n /**\n * Mass factor when spring is enabled, the higher the heavier, defaults to 1.\n */\n mass: number;\n}>;\n\n/**\n * Create a smoothing function that will smoothly tween between two values.\n * @param {number} [start] The initial value.\n * @param {SmoothToOptions} [options] Options for the transition.\n * @see https://js-toolkit.studiometa.dev/utils/math/smoothTo.html\n * @example\n * ```js\n * const x = smoothTo(0);\n * x.subscribe((value) => console.log(value));\n * x(100); // 0.1\n * ```\n */\nexport function smoothTo(start = 0, options: SmoothToOptions = {}) {\n const fns = new Set<(value: number) => any>();\n\n let damping = options.damping ?? 0.6;\n let precision = options.precision ?? 1 / 1e8;\n let stiffness = options.stiffness ?? 0.1;\n let mass = options.mass ?? 1;\n let isSpring = options.spring === true || isDefined(options.stiffness) || isDefined(options.mass);\n\n let value = start;\n let smoothed = start;\n let velocity = 0;\n\n /**\n * Callback for the useRaf service.\n */\n function tick() {\n if (isSpring) {\n [smoothed, velocity] = spring(value, smoothed, velocity, stiffness, damping, mass, precision);\n } else {\n smoothed = damp(value, smoothed, damping, precision);\n }\n\n for (const fn of fns) {\n fn(smoothed);\n }\n\n if (smoothed !== value) requestAnimationFrame(tick);\n }\n\n /**\n * Subscribe a callback to the value update.\n */\n function subscribe(fn: (value: number) => any) {\n if (isFunction(fn)) {\n fns.add(fn);\n }\n\n return () => unsubscribe(fn);\n }\n\n /**\n * Unsubscribe a callback to the value update.\n */\n function unsubscribe(fn: (value: number) => any) {\n return fns.delete(fn);\n }\n\n /**\n * Update the value if a parameter is given, get the value if no parameter is given.\n */\n function update(newValue?: number): number {\n if (!isDefined(newValue)) {\n return smoothed;\n }\n\n value = newValue;\n\n tick();\n\n return smoothed;\n }\n\n /**\n * Subscribe a callback to the value update.\n */\n update.subscribe = subscribe;\n\n /**\n * Unsubscribe a callback from the value update.\n */\n update.unsubscribe = unsubscribe;\n\n /**\n * Get the raw target value.\n */\n update.raw = () => value;\n\n /**\n * Add the given value to the current raw value.\n */\n update.add = (val: number) => update(value + val);\n\n /**\n * Get or set the damping factor.\n */\n update.damping = (val?: number) => (damping = val ?? damping);\n\n /**\n * Get or set the precision.\n */\n update.precision = (val?: number) => (precision = val ?? precision);\n\n /**\n * Get or set the stiffness factor.\n */\n update.stiffness = (val?: number) => (stiffness = val ?? stiffness);\n\n /**\n * Get or set the spring option.\n */\n update.spring = (val?: boolean) => (isSpring = val ?? isSpring);\n\n update(start);\n return update;\n}\n"],
5
+ "mappings": "AAAA,SAAS,YAAY;AACrB,SAAS,cAAc;AACvB,SAAS,YAAY,iBAAiB;AAqC/B,SAAS,SAAS,QAAQ,GAAG,UAA2B,CAAC,GAAG;AACjE,QAAM,MAAM,oBAAI,IAA4B;AAE5C,MAAI,UAAU,QAAQ,WAAW;AACjC,MAAI,YAAY,QAAQ,aAAa,IAAI;AACzC,MAAI,YAAY,QAAQ,aAAa;AACrC,MAAI,OAAO,QAAQ,QAAQ;AAC3B,MAAI,WAAW,QAAQ,WAAW,QAAQ,UAAU,QAAQ,SAAS,KAAK,UAAU,QAAQ,IAAI;AAEhG,MAAI,QAAQ;AACZ,MAAI,WAAW;AACf,MAAI,WAAW;AAKf,WAAS,OAAO;AACd,QAAI,UAAU;AACZ,OAAC,UAAU,QAAQ,IAAI,OAAO,OAAO,UAAU,UAAU,WAAW,SAAS,MAAM,SAAS;AAAA,IAC9F,OAAO;AACL,iBAAW,KAAK,OAAO,UAAU,SAAS,SAAS;AAAA,IACrD;AAEA,eAAW,MAAM,KAAK;AACpB,SAAG,QAAQ;AAAA,IACb;AAEA,QAAI,aAAa,MAAO,uBAAsB,IAAI;AAAA,EACpD;AAKA,WAAS,UAAU,IAA4B;AAC7C,QAAI,WAAW,EAAE,GAAG;AAClB,UAAI,IAAI,EAAE;AAAA,IACZ;AAEA,WAAO,MAAM,YAAY,EAAE;AAAA,EAC7B;AAKA,WAAS,YAAY,IAA4B;AAC/C,WAAO,IAAI,OAAO,EAAE;AAAA,EACtB;AAKA,WAAS,OAAO,UAA2B;AACzC,QAAI,CAAC,UAAU,QAAQ,GAAG;AACxB,aAAO;AAAA,IACT;AAEA,YAAQ;AAER,SAAK;AAEL,WAAO;AAAA,EACT;AAKA,SAAO,YAAY;AAKnB,SAAO,cAAc;AAKrB,SAAO,MAAM,MAAM;AAKnB,SAAO,MAAM,CAAC,QAAgB,OAAO,QAAQ,GAAG;AAKhD,SAAO,UAAU,CAAC,QAAkB,UAAU,OAAO;AAKrD,SAAO,YAAY,CAAC,QAAkB,YAAY,OAAO;AAKzD,SAAO,YAAY,CAAC,QAAkB,YAAY,OAAO;AAKzD,SAAO,SAAS,CAAC,QAAmB,WAAW,OAAO;AAEtD,SAAO,KAAK;AACZ,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Get the next spring value using velocity and spring physics.
3
+ * @param {number} targetValue The final value.
4
+ * @param {number} currentValue The current value.
5
+ * @param {number} currentVelocity The current velocity.
6
+ * @param {number} [stiffness=0.1] The spring stiffness (or tension) factor, defaults to 0.1.
7
+ * @param {number} [damping=0.8] The damping factor (or friction) to reduce oscillation, defaults to 0.6.
8
+ * @param {number} [mass=1] The mass factor affecting acceleration, defaults to 1.
9
+ * @param {number} [precision=1/1e4] The precision used to calculate the latest value, defaults to 1/1e4.
10
+ * @returns {[number, number]} The next value and velocity.
11
+ * @see https://js-toolkit.studiometa.dev/utils/math/spring.html
12
+ */
13
+ export declare function spring(targetValue: number, currentValue: number, currentVelocity: number, stiffness?: number, damping?: number, mass?: number, precision?: number): [number, number];
@@ -0,0 +1,11 @@
1
+ function spring(targetValue, currentValue, currentVelocity, stiffness = 0.1, damping = 0.6, mass = 1, precision = 1 / 1e4) {
2
+ const force = (targetValue - currentValue) * stiffness;
3
+ const acceleration = force / mass;
4
+ const velocity = currentVelocity * damping + acceleration;
5
+ const value = Math.abs(targetValue - currentValue) < precision && Math.abs(velocity) < precision ? targetValue : currentValue + velocity;
6
+ return [value, value === targetValue ? 0 : velocity];
7
+ }
8
+ export {
9
+ spring
10
+ };
11
+ //# sourceMappingURL=spring.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../packages/js-toolkit/utils/math/spring.ts"],
4
+ "sourcesContent": ["/**\n * Get the next spring value using velocity and spring physics.\n * @param {number} targetValue The final value.\n * @param {number} currentValue The current value.\n * @param {number} currentVelocity The current velocity.\n * @param {number} [stiffness=0.1] The spring stiffness (or tension) factor, defaults to 0.1.\n * @param {number} [damping=0.8] The damping factor (or friction) to reduce oscillation, defaults to 0.6.\n * @param {number} [mass=1] The mass factor affecting acceleration, defaults to 1.\n * @param {number} [precision=1/1e4] The precision used to calculate the latest value, defaults to 1/1e4.\n * @returns {[number, number]} The next value and velocity.\n * @see https://js-toolkit.studiometa.dev/utils/math/spring.html\n */\nexport function spring(\n targetValue: number,\n currentValue: number,\n currentVelocity: number,\n stiffness = 0.1,\n damping = 0.6,\n mass = 1,\n precision = 1 / 1e4,\n): [number, number] {\n const force = (targetValue - currentValue) * stiffness;\n const acceleration = force / mass;\n const velocity = currentVelocity * damping + acceleration;\n const value =\n Math.abs(targetValue - currentValue) < precision && Math.abs(velocity) < precision\n ? targetValue\n : currentValue + velocity;\n\n return [value, value === targetValue ? 0 : velocity];\n}\n"],
5
+ "mappings": "AAYO,SAAS,OACd,aACA,cACA,iBACA,YAAY,KACZ,UAAU,KACV,OAAO,GACP,YAAY,IAAI,KACE;AAClB,QAAM,SAAS,cAAc,gBAAgB;AAC7C,QAAM,eAAe,QAAQ;AAC7B,QAAM,WAAW,kBAAkB,UAAU;AAC7C,QAAM,QACJ,KAAK,IAAI,cAAc,YAAY,IAAI,aAAa,KAAK,IAAI,QAAQ,IAAI,YACrE,cACA,eAAe;AAErB,SAAO,CAAC,OAAO,UAAU,cAAc,IAAI,QAAQ;AACrD;",
6
+ "names": []
7
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Wrap a value in the min and max range.
3
+ */
4
+ export declare function wrap(value: number, min: number, max: number): number;
@@ -0,0 +1,8 @@
1
+ function wrap(value, min, max) {
2
+ const range = max - min;
3
+ return min === max ? min : (range + (value - min) % range) % range + min;
4
+ }
5
+ export {
6
+ wrap
7
+ };
8
+ //# sourceMappingURL=wrap.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../packages/js-toolkit/utils/math/wrap.ts"],
4
+ "sourcesContent": ["/**\n * Wrap a value in the min and max range.\n */\nexport function wrap(value: number, min: number, max: number): number {\n const range = max - min;\n return min === max ? min : ((range + ((value - min) % range)) % range) + min;\n}\n"],
5
+ "mappings": "AAGO,SAAS,KAAK,OAAe,KAAa,KAAqB;AACpE,QAAM,QAAQ,MAAM;AACpB,SAAO,QAAQ,MAAM,OAAQ,SAAU,QAAQ,OAAO,SAAU,QAAS;AAC3E;",
6
+ "names": []
7
+ }
package/utils/random.d.ts CHANGED
@@ -1,9 +1,16 @@
1
+ /**
2
+ * Get a random number between given bounds.
3
+ * @param {number} a First bound.
4
+ * @param {number} [b] Second bound, defaults to 0.
5
+ * @returns {number} A number between `a` and `b`.
6
+ */
7
+ export declare function random(a: number, b?: number): number;
1
8
  /**
2
9
  * Get a random integer between bounds
3
10
  *
4
- * @param {number} a Lower bound
5
- * @param {number} b Upper bound
6
- * @returns {number}
11
+ * @param {number} a First bound.
12
+ * @param {number} b Second bound.
13
+ * @returns {number} An integer between `a` and `b`;
7
14
  */
8
15
  export declare function randomInt(a: number, b?: number): number;
9
16
  /**
@@ -11,5 +18,6 @@ export declare function randomInt(a: number, b?: number): number;
11
18
  *
12
19
  * @param {T[] | string} items Array or string
13
20
  * @returns {T | undefined}
21
+ * @throws {Error} Throws an error if `items` is not an array or a string.
14
22
  */
15
23
  export declare function randomItem<T>(items: T[] | string): T | string | undefined;
package/utils/random.js CHANGED
@@ -1,6 +1,9 @@
1
1
  import { isArray, isString } from "./is.js";
2
+ function random(a, b = 0) {
3
+ return Math.random() * (b - a) + a;
4
+ }
2
5
  function randomInt(a, b = 0) {
3
- return Math.floor(Math.random() * (a - b + 1)) + b;
6
+ return Math.round(random(a, b));
4
7
  }
5
8
  function randomItem(items) {
6
9
  if (!isArray(items) && !isString(items)) {
@@ -9,6 +12,7 @@ function randomItem(items) {
9
12
  return items.length > 0 ? items[randomInt(items.length - 1)] : void 0;
10
13
  }
11
14
  export {
15
+ random,
12
16
  randomInt,
13
17
  randomItem
14
18
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/utils/random.ts"],
4
- "sourcesContent": ["import { isArray, isString } from './is.js';\n\n/**\n * Get a random integer between bounds\n *\n * @param {number} a Lower bound\n * @param {number} b Upper bound\n * @returns {number}\n */\nexport function randomInt(a: number, b = 0): number {\n return Math.floor(Math.random() * (a - b + 1)) + b;\n}\n\n/**\n * Get a random item of an array or a random character of a string\n *\n * @param {T[] | string} items Array or string\n * @returns {T | undefined}\n */\nexport function randomItem<T>(items: T[] | string): T | string | undefined {\n if (!isArray(items) && !isString(items)) {\n throw new Error('randomItem() expects an array or a string as argument.');\n }\n return items.length > 0 ? items[randomInt(items.length - 1)] : undefined;\n}\n"],
5
- "mappings": "AAAA,SAAS,SAAS,gBAAgB;AAS3B,SAAS,UAAU,GAAW,IAAI,GAAW;AAClD,SAAO,KAAK,MAAM,KAAK,OAAO,KAAK,IAAI,IAAI,EAAE,IAAI;AACnD;AAQO,SAAS,WAAc,OAA6C;AACzE,MAAI,CAAC,QAAQ,KAAK,KAAK,CAAC,SAAS,KAAK,GAAG;AACvC,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,SAAO,MAAM,SAAS,IAAI,MAAM,UAAU,MAAM,SAAS,CAAC,CAAC,IAAI;AACjE;",
4
+ "sourcesContent": ["import { isArray, isString } from './is.js';\n\n/**\n * Get a random number between given bounds.\n * @param {number} a First bound.\n * @param {number} [b] Second bound, defaults to 0.\n * @returns {number} A number between `a` and `b`.\n */\nexport function random(a: number, b = 0): number {\n return Math.random() * (b - a) + a;\n}\n\n/**\n * Get a random integer between bounds\n *\n * @param {number} a First bound.\n * @param {number} b Second bound.\n * @returns {number} An integer between `a` and `b`;\n */\nexport function randomInt(a: number, b = 0): number {\n return Math.round(random(a, b));\n}\n\n/**\n * Get a random item of an array or a random character of a string\n *\n * @param {T[] | string} items Array or string\n * @returns {T | undefined}\n * @throws {Error} Throws an error if `items` is not an array or a string.\n */\nexport function randomItem<T>(items: T[] | string): T | string | undefined {\n if (!isArray(items) && !isString(items)) {\n throw new Error('randomItem() expects an array or a string as argument.');\n }\n return items.length > 0 ? items[randomInt(items.length - 1)] : undefined;\n}\n"],
5
+ "mappings": "AAAA,SAAS,SAAS,gBAAgB;AAQ3B,SAAS,OAAO,GAAW,IAAI,GAAW;AAC/C,SAAO,KAAK,OAAO,KAAK,IAAI,KAAK;AACnC;AASO,SAAS,UAAU,GAAW,IAAI,GAAW;AAClD,SAAO,KAAK,MAAM,OAAO,GAAG,CAAC,CAAC;AAChC;AASO,SAAS,WAAc,OAA6C;AACzE,MAAI,CAAC,QAAQ,KAAK,KAAK,CAAC,SAAS,KAAK,GAAG;AACvC,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA,SAAO,MAAM,SAAS,IAAI,MAAM,UAAU,MAAM,SAAS,CAAC,CAAC,IAAI;AACjE;",
6
6
  "names": []
7
7
  }
package/utils/tween.d.ts CHANGED
@@ -45,9 +45,18 @@ export interface TweenOptions {
45
45
  * The smooth factor. Setting this option to `true` or a `number` will disable the `duration` option.
46
46
  */
47
47
  smooth?: true | number;
48
+ /**
49
+ * Enable spring transition. Setting this option to `true` or a `number` will disable the `duration` option.
50
+ * If `true`, a default stiffness of 0.1 will be used, if a `number` is given, it will be used instead.
51
+ */
52
+ spring?: true | number;
53
+ /**
54
+ * When spring physics are enabled, use the mass option to make the object heavier or lighter. Defaults to `1`.
55
+ */
56
+ mass?: number;
48
57
  /**
49
58
  * The precision for when to consider the tween finished.
50
- * Defaults to `0.0001`.
59
+ * Defaults to `0.00001`.
51
60
  */
52
61
  precision?: number;
53
62
  /**
@@ -69,5 +78,6 @@ export interface TweenOptions {
69
78
  export declare function normalizeEase(ease: EasingFunction | BezierCurve): EasingFunction;
70
79
  /**
71
80
  * Tween from 0 to 1.
81
+ * @see https://js-toolkit.studiometa.dev/utils/tween.html
72
82
  */
73
83
  export declare function tween(callback: (progress: number) => unknown, options?: TweenOptions): Tween;
package/utils/tween.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { cubicBezier } from "@motionone/easing";
2
- import { lerp, map, clamp01, damp, inertiaFinalValue } from "./math/index.js";
2
+ import { lerp, map, clamp01, damp, inertiaFinalValue, spring } from "./math/index.js";
3
3
  import { isDefined, isArray, isNumber } from "./is.js";
4
4
  import { noop, noopValue as linear } from "./noop.js";
5
5
  import { useRaf } from "../services/RafService.js";
6
6
  let id = 0;
7
- const DEFAULT_PROGRESS_PRECISION = 1e-4;
7
+ const DEFAULT_PROGRESS_PRECISION = 1 / 1e4;
8
8
  function normalizeEase(ease) {
9
9
  if (!isDefined(ease)) {
10
10
  return linear;
@@ -18,8 +18,12 @@ function tween(callback, options = {}) {
18
18
  const raf = useRaf();
19
19
  let progressValue = 0;
20
20
  let easedProgress = 0;
21
+ let velocity = 0;
21
22
  const isSmooth = isDefined(options.smooth) && (isNumber(options.smooth) || options.smooth);
22
- const smoothFactor = isNumber(options.smooth) ? options.smooth : 0.1;
23
+ const isSpring = isDefined(options.spring) && (isNumber(options.spring) || options.spring);
24
+ const stiffness = isNumber(options.spring) ? options.spring : 0.1;
25
+ const mass = isNumber(options.mass) ? options.mass : 1;
26
+ const damping = isNumber(options.smooth) ? options.smooth : 0.1;
23
27
  const precision = options.precision ?? DEFAULT_PROGRESS_PRECISION;
24
28
  const ease = normalizeEase(options.easing);
25
29
  let delay = options.delay ?? 0;
@@ -40,15 +44,29 @@ function tween(callback, options = {}) {
40
44
  if (!isDefined(newProgress)) {
41
45
  return easedProgress;
42
46
  }
47
+ let shouldStop = false;
43
48
  progressValue = newProgress;
44
- easedProgress = isSmooth ? damp(progressValue, easedProgress, smoothFactor, precision) : ease(progressValue);
49
+ if (isSpring) {
50
+ [easedProgress, velocity] = spring(
51
+ progressValue,
52
+ easedProgress,
53
+ velocity,
54
+ stiffness,
55
+ damping,
56
+ mass,
57
+ precision
58
+ );
59
+ } else {
60
+ easedProgress = isSmooth ? damp(progressValue, easedProgress, damping, precision) : ease(progressValue);
61
+ }
45
62
  if (Math.abs(1 - easedProgress) < precision) {
46
63
  progressValue = 1;
47
64
  easedProgress = 1;
65
+ shouldStop = true;
48
66
  }
49
67
  callback(easedProgress);
50
68
  onProgress(easedProgress);
51
- if (easedProgress === 1) {
69
+ if (shouldStop) {
52
70
  pause();
53
71
  requestAnimationFrame(() => onFinish(easedProgress));
54
72
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/js-toolkit/utils/tween.ts"],
4
- "sourcesContent": ["import { cubicBezier } from '@motionone/easing';\nimport { lerp, map, clamp01, damp, inertiaFinalValue } from './math/index.js';\nimport { isDefined, isArray, isNumber } from './is.js';\nimport { noop, noopValue as linear } from './noop.js';\nimport { useRaf } from '../services/RafService.js';\nimport type { EasingFunction } from './math/createEases.js';\n\nlet id = 0;\nconst DEFAULT_PROGRESS_PRECISION = 0.0001;\n\nexport type BezierCurve = [number, number, number, number];\n\n/**\n * Controls for a tween.\n */\nexport interface Tween {\n /**\n * Start the tween from the beginning.\n */\n start: () => void;\n /**\n * Finish the tween and set its state to the end.\n */\n finish: () => void;\n /**\n * Pause the tween.\n */\n pause: () => void;\n /**\n * Start the tween from the current paused progress.\n */\n play: () => void;\n /**\n * Set and get the tween's progress.\n */\n progress: (progress?: number) => number;\n}\n\nexport interface TweenOptions {\n /**\n * The duration, in seconds.\n * Defaults to `1`.\n */\n duration?: number;\n /**\n * The delay, in seconds.\n * Defaults to `0`.\n */\n delay?: number;\n /**\n * The easing function or bezier curve to use.\n * Defaults to a linear easing function.\n */\n easing?: EasingFunction | BezierCurve;\n /**\n * The smooth factor. Setting this option to `true` or a `number` will disable the `duration` option.\n */\n smooth?: true | number;\n /**\n * The precision for when to consider the tween finished.\n * Defaults to `0.0001`.\n */\n precision?: number;\n /**\n * A callback executed on start.\n */\n onStart?: (progress: number) => void;\n /**\n * A callback executed each time the progress is updated.\n */\n onProgress?: (progress: number) => void;\n /**\n * A callback executed when the tween is finished.\n */\n onFinish?: (progress: number) => void;\n}\n\n/**\n * Normalize a easing function with default fallbacks.\n */\nexport function normalizeEase(ease: EasingFunction | BezierCurve): EasingFunction {\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 */\nexport function tween(callback: (progress: number) => unknown, options: TweenOptions = {}): Tween {\n const raf = useRaf();\n\n let progressValue = 0;\n let easedProgress = 0;\n\n const isSmooth = isDefined(options.smooth) && (isNumber(options.smooth) || options.smooth);\n const smoothFactor = isNumber(options.smooth) ? options.smooth : 0.1;\n const precision = options.precision ?? DEFAULT_PROGRESS_PRECISION;\n const ease = normalizeEase(options.easing);\n\n let delay = options.delay ?? 0;\n delay *= 1000;\n let duration = options.duration ?? 1;\n duration *= 1000;\n\n /* eslint-disable @typescript-eslint/no-use-before-define */\n let startTime = getStartTime();\n let endTime = getEndTime(startTime);\n /* eslint-enable @typescript-eslint/no-use-before-define */\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 function pause() {\n isRunning = false;\n raf.remove(key);\n }\n\n /**\n * Set the progress value.\n */\n function progress(newProgress: number) {\n if (!isDefined(newProgress)) {\n return easedProgress;\n }\n\n progressValue = newProgress;\n easedProgress = isSmooth\n ? damp(progressValue, easedProgress, smoothFactor, precision)\n : ease(progressValue);\n\n // Stop when reaching precision\n if (Math.abs(1 - easedProgress) < precision) {\n progressValue = 1;\n easedProgress = 1;\n }\n\n callback(easedProgress);\n onProgress(easedProgress);\n\n if (easedProgress === 1) {\n pause();\n requestAnimationFrame(() => onFinish(easedProgress));\n }\n\n return easedProgress;\n }\n\n /**\n * Loop for rendering the animation.\n */\n function tick(props: { time: number }) {\n progress(clamp01(map(props.time, startTime, endTime, 0, 1)));\n }\n\n function getStartTime() {\n return performance.now() + delay;\n }\n\n function getEndTime(time: number) {\n return isSmooth ? inertiaFinalValue(time, 1) : time + duration;\n }\n\n /**\n * Play the animation.\n */\n function start() {\n onStart(0);\n startTime = getStartTime();\n endTime = getEndTime(startTime);\n progressValue = 0;\n easedProgress = 0;\n isRunning = true;\n\n raf.add(key, tick);\n }\n\n /**\n * Play a paused animation.\n */\n function play() {\n if (isRunning) {\n return;\n }\n\n startTime = getStartTime() - lerp(0, duration, progressValue);\n endTime = getEndTime(startTime);\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
- "mappings": "AAAA,SAAS,mBAAmB;AAC5B,SAAS,MAAM,KAAK,SAAS,MAAM,yBAAyB;AAC5D,SAAS,WAAW,SAAS,gBAAgB;AAC7C,SAAS,MAAM,aAAa,cAAc;AAC1C,SAAS,cAAc;AAGvB,IAAI,KAAK;AACT,MAAM,6BAA6B;AAwE5B,SAAS,cAAc,MAAoD;AAChF,MAAI,CAAC,UAAU,IAAI,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,IAAI,GAAG;AACjB,WAAO,YAAY,GAAG,IAAI;AAAA,EAC5B;AAEA,SAAO;AACT;AAKO,SAAS,MAAM,UAAyC,UAAwB,CAAC,GAAU;AAChG,QAAM,MAAM,OAAO;AAEnB,MAAI,gBAAgB;AACpB,MAAI,gBAAgB;AAEpB,QAAM,WAAW,UAAU,QAAQ,MAAM,MAAM,SAAS,QAAQ,MAAM,KAAK,QAAQ;AACnF,QAAM,eAAe,SAAS,QAAQ,MAAM,IAAI,QAAQ,SAAS;AACjE,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,OAAO,cAAc,QAAQ,MAAM;AAEzC,MAAI,QAAQ,QAAQ,SAAS;AAC7B,WAAS;AACT,MAAI,WAAW,QAAQ,YAAY;AACnC,cAAY;AAGZ,MAAI,YAAY,aAAa;AAC7B,MAAI,UAAU,WAAW,SAAS;AAGlC,QAAM,MAAM,MAAM,EAAE;AACpB,QAAM;AAEN,QAAM,EAAE,UAAU,MAAM,aAAa,MAAM,WAAW,KAAK,IAAI;AAC/D,MAAI,YAAY;AAKhB,WAAS,QAAQ;AACf,gBAAY;AACZ,QAAI,OAAO,GAAG;AAAA,EAChB;AAKA,WAAS,SAAS,aAAqB;AACrC,QAAI,CAAC,UAAU,WAAW,GAAG;AAC3B,aAAO;AAAA,IACT;AAEA,oBAAgB;AAChB,oBAAgB,WACZ,KAAK,eAAe,eAAe,cAAc,SAAS,IAC1D,KAAK,aAAa;AAGtB,QAAI,KAAK,IAAI,IAAI,aAAa,IAAI,WAAW;AAC3C,sBAAgB;AAChB,sBAAgB;AAAA,IAClB;AAEA,aAAS,aAAa;AACtB,eAAW,aAAa;AAExB,QAAI,kBAAkB,GAAG;AACvB,YAAM;AACN,4BAAsB,MAAM,SAAS,aAAa,CAAC;AAAA,IACrD;AAEA,WAAO;AAAA,EACT;AAKA,WAAS,KAAK,OAAyB;AACrC,aAAS,QAAQ,IAAI,MAAM,MAAM,WAAW,SAAS,GAAG,CAAC,CAAC,CAAC;AAAA,EAC7D;AAEA,WAAS,eAAe;AACtB,WAAO,YAAY,IAAI,IAAI;AAAA,EAC7B;AAEA,WAAS,WAAW,MAAc;AAChC,WAAO,WAAW,kBAAkB,MAAM,CAAC,IAAI,OAAO;AAAA,EACxD;AAKA,WAAS,QAAQ;AACf,YAAQ,CAAC;AACT,gBAAY,aAAa;AACzB,cAAU,WAAW,SAAS;AAC9B,oBAAgB;AAChB,oBAAgB;AAChB,gBAAY;AAEZ,QAAI,IAAI,KAAK,IAAI;AAAA,EACnB;AAKA,WAAS,OAAO;AACd,QAAI,WAAW;AACb;AAAA,IACF;AAEA,gBAAY,aAAa,IAAI,KAAK,GAAG,UAAU,aAAa;AAC5D,cAAU,WAAW,SAAS;AAC9B,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;",
4
+ "sourcesContent": ["import { cubicBezier } from '@motionone/easing';\nimport { lerp, map, clamp01, damp, inertiaFinalValue, spring } from './math/index.js';\nimport { isDefined, isArray, isNumber } from './is.js';\nimport { noop, noopValue as linear } from './noop.js';\nimport { useRaf } from '../services/RafService.js';\nimport type { EasingFunction } from './math/createEases.js';\n\nlet id = 0;\nconst DEFAULT_PROGRESS_PRECISION = 1 / 1e4;\n\nexport type BezierCurve = [number, number, number, number];\n\n/**\n * Controls for a tween.\n */\nexport interface Tween {\n /**\n * Start the tween from the beginning.\n */\n start: () => void;\n /**\n * Finish the tween and set its state to the end.\n */\n finish: () => void;\n /**\n * Pause the tween.\n */\n pause: () => void;\n /**\n * Start the tween from the current paused progress.\n */\n play: () => void;\n /**\n * Set and get the tween's progress.\n */\n progress: (progress?: number) => number;\n}\n\nexport interface TweenOptions {\n /**\n * The duration, in seconds.\n * Defaults to `1`.\n */\n duration?: number;\n /**\n * The delay, in seconds.\n * Defaults to `0`.\n */\n delay?: number;\n /**\n * The easing function or bezier curve to use.\n * Defaults to a linear easing function.\n */\n easing?: EasingFunction | BezierCurve;\n /**\n * The smooth factor. Setting this option to `true` or a `number` will disable the `duration` option.\n */\n smooth?: true | number;\n /**\n * Enable spring transition. Setting this option to `true` or a `number` will disable the `duration` option.\n * If `true`, a default stiffness of 0.1 will be used, if a `number` is given, it will be used instead.\n */\n spring?: true | number;\n /**\n * When spring physics are enabled, use the mass option to make the object heavier or lighter. Defaults to `1`.\n */\n mass?: number;\n /**\n * The precision for when to consider the tween finished.\n * Defaults to `0.00001`.\n */\n precision?: number;\n /**\n * A callback executed on start.\n */\n onStart?: (progress: number) => void;\n /**\n * A callback executed each time the progress is updated.\n */\n onProgress?: (progress: number) => void;\n /**\n * A callback executed when the tween is finished.\n */\n onFinish?: (progress: number) => void;\n}\n\n/**\n * Normalize a easing function with default fallbacks.\n */\nexport function normalizeEase(ease: EasingFunction | BezierCurve): EasingFunction {\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 * @see https://js-toolkit.studiometa.dev/utils/tween.html\n */\nexport function tween(callback: (progress: number) => unknown, options: TweenOptions = {}): Tween {\n const raf = useRaf();\n\n let progressValue = 0;\n let easedProgress = 0;\n let velocity = 0;\n\n const isSmooth = isDefined(options.smooth) && (isNumber(options.smooth) || options.smooth);\n const isSpring = isDefined(options.spring) && (isNumber(options.spring) || options.spring);\n const stiffness = isNumber(options.spring) ? options.spring : 0.1;\n const mass = isNumber(options.mass) ? options.mass : 1;\n const damping = isNumber(options.smooth) ? options.smooth : 0.1;\n const precision = options.precision ?? DEFAULT_PROGRESS_PRECISION;\n const ease = normalizeEase(options.easing);\n\n let delay = options.delay ?? 0;\n delay *= 1000;\n let duration = options.duration ?? 1;\n duration *= 1000;\n\n /* eslint-disable @typescript-eslint/no-use-before-define */\n let startTime = getStartTime();\n let endTime = getEndTime(startTime);\n /* eslint-enable @typescript-eslint/no-use-before-define */\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 function pause() {\n isRunning = false;\n raf.remove(key);\n }\n\n /**\n * Set the progress value.\n */\n function progress(newProgress: number) {\n if (!isDefined(newProgress)) {\n return easedProgress;\n }\n\n let shouldStop = false;\n\n progressValue = newProgress;\n if (isSpring) {\n [easedProgress, velocity] = spring(\n progressValue,\n easedProgress,\n velocity,\n stiffness,\n damping,\n mass,\n precision,\n );\n } else {\n easedProgress = isSmooth\n ? damp(progressValue, easedProgress, damping, precision)\n : ease(progressValue);\n }\n\n // Stop when reaching precision\n if (Math.abs(1 - easedProgress) < precision) {\n progressValue = 1;\n easedProgress = 1;\n shouldStop = true;\n }\n\n callback(easedProgress);\n onProgress(easedProgress);\n\n if (shouldStop) {\n pause();\n requestAnimationFrame(() => onFinish(easedProgress));\n }\n\n return easedProgress;\n }\n\n /**\n * Loop for rendering the animation.\n */\n function tick(props: { time: number }) {\n progress(clamp01(map(props.time, startTime, endTime, 0, 1)));\n }\n\n function getStartTime() {\n return performance.now() + delay;\n }\n\n function getEndTime(time: number) {\n return isSmooth ? inertiaFinalValue(time, 1) : time + duration;\n }\n\n /**\n * Play the animation.\n */\n function start() {\n onStart(0);\n startTime = getStartTime();\n endTime = getEndTime(startTime);\n progressValue = 0;\n easedProgress = 0;\n isRunning = true;\n\n raf.add(key, tick);\n }\n\n /**\n * Play a paused animation.\n */\n function play() {\n if (isRunning) {\n return;\n }\n\n startTime = getStartTime() - lerp(0, duration, progressValue);\n endTime = getEndTime(startTime);\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
+ "mappings": "AAAA,SAAS,mBAAmB;AAC5B,SAAS,MAAM,KAAK,SAAS,MAAM,mBAAmB,cAAc;AACpE,SAAS,WAAW,SAAS,gBAAgB;AAC7C,SAAS,MAAM,aAAa,cAAc;AAC1C,SAAS,cAAc;AAGvB,IAAI,KAAK;AACT,MAAM,6BAA6B,IAAI;AAiFhC,SAAS,cAAc,MAAoD;AAChF,MAAI,CAAC,UAAU,IAAI,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,IAAI,GAAG;AACjB,WAAO,YAAY,GAAG,IAAI;AAAA,EAC5B;AAEA,SAAO;AACT;AAMO,SAAS,MAAM,UAAyC,UAAwB,CAAC,GAAU;AAChG,QAAM,MAAM,OAAO;AAEnB,MAAI,gBAAgB;AACpB,MAAI,gBAAgB;AACpB,MAAI,WAAW;AAEf,QAAM,WAAW,UAAU,QAAQ,MAAM,MAAM,SAAS,QAAQ,MAAM,KAAK,QAAQ;AACnF,QAAM,WAAW,UAAU,QAAQ,MAAM,MAAM,SAAS,QAAQ,MAAM,KAAK,QAAQ;AACnF,QAAM,YAAY,SAAS,QAAQ,MAAM,IAAI,QAAQ,SAAS;AAC9D,QAAM,OAAO,SAAS,QAAQ,IAAI,IAAI,QAAQ,OAAO;AACrD,QAAM,UAAU,SAAS,QAAQ,MAAM,IAAI,QAAQ,SAAS;AAC5D,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,OAAO,cAAc,QAAQ,MAAM;AAEzC,MAAI,QAAQ,QAAQ,SAAS;AAC7B,WAAS;AACT,MAAI,WAAW,QAAQ,YAAY;AACnC,cAAY;AAGZ,MAAI,YAAY,aAAa;AAC7B,MAAI,UAAU,WAAW,SAAS;AAGlC,QAAM,MAAM,MAAM,EAAE;AACpB,QAAM;AAEN,QAAM,EAAE,UAAU,MAAM,aAAa,MAAM,WAAW,KAAK,IAAI;AAC/D,MAAI,YAAY;AAKhB,WAAS,QAAQ;AACf,gBAAY;AACZ,QAAI,OAAO,GAAG;AAAA,EAChB;AAKA,WAAS,SAAS,aAAqB;AACrC,QAAI,CAAC,UAAU,WAAW,GAAG;AAC3B,aAAO;AAAA,IACT;AAEA,QAAI,aAAa;AAEjB,oBAAgB;AAChB,QAAI,UAAU;AACZ,OAAC,eAAe,QAAQ,IAAI;AAAA,QAC1B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,sBAAgB,WACZ,KAAK,eAAe,eAAe,SAAS,SAAS,IACrD,KAAK,aAAa;AAAA,IACxB;AAGA,QAAI,KAAK,IAAI,IAAI,aAAa,IAAI,WAAW;AAC3C,sBAAgB;AAChB,sBAAgB;AAChB,mBAAa;AAAA,IACf;AAEA,aAAS,aAAa;AACtB,eAAW,aAAa;AAExB,QAAI,YAAY;AACd,YAAM;AACN,4BAAsB,MAAM,SAAS,aAAa,CAAC;AAAA,IACrD;AAEA,WAAO;AAAA,EACT;AAKA,WAAS,KAAK,OAAyB;AACrC,aAAS,QAAQ,IAAI,MAAM,MAAM,WAAW,SAAS,GAAG,CAAC,CAAC,CAAC;AAAA,EAC7D;AAEA,WAAS,eAAe;AACtB,WAAO,YAAY,IAAI,IAAI;AAAA,EAC7B;AAEA,WAAS,WAAW,MAAc;AAChC,WAAO,WAAW,kBAAkB,MAAM,CAAC,IAAI,OAAO;AAAA,EACxD;AAKA,WAAS,QAAQ;AACf,YAAQ,CAAC;AACT,gBAAY,aAAa;AACzB,cAAU,WAAW,SAAS;AAC9B,oBAAgB;AAChB,oBAAgB;AAChB,gBAAY;AAEZ,QAAI,IAAI,KAAK,IAAI;AAAA,EACnB;AAKA,WAAS,OAAO;AACd,QAAI,WAAW;AACb;AAAA,IACF;AAEA,gBAAY,aAAa,IAAI,KAAK,GAAG,UAAU,aAAa;AAC5D,cAAU,WAAW,SAAS;AAC9B,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
  }