@rafaelaugusto/jolt 0.1.0-beta.0 → 0.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/presets.js CHANGED
@@ -67,28 +67,30 @@ export const presets = {
67
67
  },
68
68
  pulse: {
69
69
  keyframes: { scale: [1, 1.06, 1] },
70
- transition: { duration: 500, ease: 'easeInOut' },
70
+ transition: { duration: 500, ease: 'easeInOut', relative: true },
71
71
  },
72
72
  bounce: {
73
73
  keyframes: { y: [0, -18, 0, -8, 0] },
74
74
  transition: {
75
75
  duration: 650,
76
+ relative: true,
76
77
  times: [0, 0.3, 0.6, 0.8, 1],
77
78
  ease: ['easeOut', 'easeIn', 'easeOut', 'easeIn'],
78
79
  },
79
80
  },
80
81
  shake: {
81
82
  keyframes: { x: [0, -10, 10, -8, 8, -4, 4, 0] },
82
- transition: { duration: 500, ease: 'easeInOut' },
83
+ transition: { duration: 500, ease: 'easeInOut', relative: true },
83
84
  },
84
85
  wiggle: {
85
86
  keyframes: { rotate: [0, -8, 8, -5, 5, 0] },
86
- transition: { duration: 500, ease: 'easeInOut' },
87
+ transition: { duration: 500, ease: 'easeInOut', relative: true },
87
88
  },
88
89
  heartbeat: {
89
90
  keyframes: { scale: [1, 1.15, 1, 1.15, 1, 1] },
90
91
  transition: {
91
92
  duration: 1000,
93
+ relative: true,
92
94
  times: [0, 0.14, 0.28, 0.42, 0.7, 1],
93
95
  ease: 'easeInOut',
94
96
  },
@@ -100,24 +102,40 @@ export const presets = {
100
102
  },
101
103
  transition: {
102
104
  duration: 800,
105
+ relative: true,
103
106
  times: [0, 0.3, 0.4, 0.5, 0.65, 0.75, 1],
104
107
  ease: 'easeInOut',
105
108
  },
106
109
  },
107
110
  flash: {
108
111
  keyframes: { opacity: [1, 0, 1, 0, 1] },
109
- transition: { duration: 800, ease: 'easeInOut' },
112
+ transition: { duration: 800, ease: 'easeInOut', relative: true },
110
113
  },
111
114
  tada: {
112
115
  keyframes: {
113
116
  scale: [1, 0.9, 0.9, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1],
114
117
  rotate: [0, -3, -3, 3, -3, 3, -3, 3, -3, 3, 0],
115
118
  },
116
- transition: { duration: 1000, ease: 'easeInOut' },
119
+ transition: { duration: 1000, ease: 'easeInOut', relative: true },
117
120
  },
118
121
  spin: {
119
122
  keyframes: { rotate: [0, 360] },
120
- transition: { duration: 1000, ease: 'linear' },
123
+ transition: { duration: 1000, ease: 'linear', relative: true },
121
124
  },
122
125
  };
126
+ const customPresets = new Map();
127
+ /** Registers a custom preset. Registering it again replaces it for future animations. */
128
+ export function definePreset(name, preset) {
129
+ if (Object.hasOwn(presets, name)) {
130
+ throw new Error(`Preset "${name}" is built in and cannot be replaced.`);
131
+ }
132
+ customPresets.set(name, preset);
133
+ }
134
+ export function getPreset(name) {
135
+ const preset = customPresets.get(name) ??
136
+ (Object.hasOwn(presets, name) ? presets[name] : undefined);
137
+ if (!preset)
138
+ throw new Error(`Unknown preset "${name}".`);
139
+ return preset;
140
+ }
123
141
  //# sourceMappingURL=presets.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"presets.js","sourceRoot":"","sources":["../src/presets.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAW,CAAA;AAC1D,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAW,CAAA;AAC1D,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAW,CAAA;AAEnE,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,MAAM,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE;IAC9D,QAAQ,EAAE;QACR,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE;QAC1C,UAAU,EAAE,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE;KAC1C;IACD,UAAU,EAAE;QACV,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE;QAC3C,UAAU,EAAE,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE;KAC1C;IACD,UAAU,EAAE;QACV,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE;QAC3C,UAAU,EAAE,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE;KAC1C;IACD,WAAW,EAAE;QACX,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE;QAC1C,UAAU,EAAE,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE;KAC1C;IACD,MAAM,EAAE;QACN,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE;QAChD,UAAU,EAAE,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE;KAC1C;IACD,KAAK,EAAE;QACL,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE;QAC/C,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,GAAG;YACb,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE;SAC3B;KACF;IACD,OAAO,EAAE;QACP,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE;QACjD,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,GAAG;YACb,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE;SAC3B;KACF;IACD,OAAO,EAAE;QACP,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE;QAChD,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,GAAG;YACb,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE;SAC3B;KACF;IAED,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE;IAC3D,SAAS,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE;IACrE,WAAW,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE;IACtE,WAAW,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE;IACvE,YAAY,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE;IACvE,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE;IACxE,MAAM,EAAE;QACN,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE;QACnD,UAAU,EAAE;YACV,QAAQ,EAAE,GAAG;YACb,IAAI,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC;YAC3B,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;YAClB,OAAO,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE;SAC3C;KACF;IAED,KAAK,EAAE;QACL,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QAClC,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE;KACjD;IACD,MAAM,EAAE;QACN,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;QACpC,UAAU,EAAE;YACV,QAAQ,EAAE,GAAG;YACb,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;YAC5B,IAAI,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;SACjD;KACF;IACD,KAAK,EAAE;QACL,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;QAC/C,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE;KACjD;IACD,MAAM,EAAE;QACN,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;QAC3C,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE;KACjD;IACD,SAAS,EAAE;QACT,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;QAC9C,UAAU,EAAE;YACV,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YACpC,IAAI,EAAE,WAAW;SAClB;KACF;IACD,KAAK,EAAE;QACL,SAAS,EAAE;YACT,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5C,MAAM,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;SAC7C;QACD,UAAU,EAAE;YACV,QAAQ,EAAE,GAAG;YACb,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACxC,IAAI,EAAE,WAAW;SAClB;KACF;IACD,KAAK,EAAE;QACL,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE;QACvC,UAAU,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE;KACjD;IACD,IAAI,EAAE;QACJ,SAAS,EAAE;YACT,KAAK,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;YAC1D,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;SAC/C;QACD,UAAU,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE;KAClD;IACD,IAAI,EAAE;QACJ,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;QAC/B,UAAU,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE;KAC/C;CAC+B,CAAA"}
1
+ {"version":3,"file":"presets.js","sourceRoot":"","sources":["../src/presets.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"press.d.ts","sourceRoot":"","sources":["../src/press.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,iBAAiB,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAKnE;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CACnB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,SAA2B,EACpC,OAAO,CAAC,EAAE,cAAc,GAAG,UAAU,GACpC,MAAM,IAAI,CAoBZ"}
1
+ {"version":3,"file":"press.d.ts","sourceRoot":"","sources":["../src/press.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,iBAAiB,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAKnE;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CACnB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,SAA2B,EACpC,OAAO,CAAC,EAAE,cAAc,GAAG,UAAU,GACpC,MAAM,IAAI,CA0BZ"}
package/dist/press.js CHANGED
@@ -22,7 +22,9 @@ export function press(target, pressed = { scale: 0.96 }, options) {
22
22
  animate(view, pressed, options ?? pressIn);
23
23
  }
24
24
  else if ((action === 'up' || action === 'cancel') && rest) {
25
- animate(view, rest, options ?? release);
25
+ animate(view, rest, typeof options === 'object'
26
+ ? { ...options, relative: false }
27
+ : (options ?? release));
26
28
  rest = undefined;
27
29
  }
28
30
  };
package/dist/press.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"press.js","sourceRoot":"","sources":["../src/press.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAiB,MAAM,iBAAiB,CAAA;AAItE,MAAM,OAAO,GAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,CAAA;AACxE,MAAM,OAAO,GAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;AAE3E;;;;;;;;GAQG;AACH,MAAM,UAAU,KAAK,CACnB,MAAc,EACd,OAAO,GAAc,EAAE,KAAK,EAAE,IAAI,EAAE,EACpC,OAAqC;IAErC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;IAC3B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAc,EAAE,CAClE,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CACtE,CAAA;IACD,IAAI,IAA2B,CAAA;IAE/B,MAAM,OAAO,GAAG,CAAC,KAAgB,EAAE,EAAE;QACnC,MAAM,EAAE,MAAM,EAAE,GAAG,KAA8B,CAAA;QACjD,IAAI,MAAM,KAAK,MAAM,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;YAC3D,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACzE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,IAAI,OAAO,CAAC,CAAA;QAC5C,CAAC;aAAM,IAAI,CAAC,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;YAC5D,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,IAAI,OAAO,CAAC,CAAA;YACvC,IAAI,GAAG,SAAS,CAAA;QAClB,CAAC;IACH,CAAC,CAAA;IAED,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACzB,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AACzC,CAAC"}
1
+ {"version":3,"file":"press.js","sourceRoot":"","sources":["../src/press.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAiB,MAAM,iBAAiB,CAAA;AAItE,MAAM,OAAO,GAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,CAAA;AACxE,MAAM,OAAO,GAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;AAE3E;;;;;;;;GAQG;AACH,MAAM,UAAU,KAAK,CACnB,MAAc,EACd,OAAO,GAAc,EAAE,KAAK,EAAE,IAAI,EAAE,EACpC,OAAqC;IAErC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;IAC3B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAc,EAAE,CAClE,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CACtE,CAAA;IACD,IAAI,IAA2B,CAAA;IAE/B,MAAM,OAAO,GAAG,CAAC,KAAgB,EAAE,EAAE;QACnC,MAAM,EAAE,MAAM,EAAE,GAAG,KAA8B,CAAA;QACjD,IAAI,MAAM,KAAK,MAAM,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;YAC3D,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YACzE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,IAAI,OAAO,CAAC,CAAA;QAC5C,CAAC;aAAM,IAAI,CAAC,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;YAC5D,OAAO,CACL,IAAI,EACJ,IAAI,EACJ,OAAO,OAAO,KAAK,QAAQ;gBACzB,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;gBACjC,CAAC,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CACzB,CAAA;YACD,IAAI,GAAG,SAAS,CAAA;QAClB,CAAC;IACH,CAAC,CAAA;IAED,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IACzB,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AACzC,CAAC"}
@@ -10,8 +10,9 @@ export type Step = readonly [
10
10
  /**
11
11
  * Plays steps one after the other. A step starts once the previous one looks
12
12
  * done: a spring is close to its target, even if it hasn't fully settled.
13
- * Views in later steps take their first keyframe right away, so a title that
14
- * fades in third doesn't show up before its turn.
13
+ * Views in later steps take their first absolute keyframe right away, so a title
14
+ * that fades in third doesn't show up before its turn. Relative and null keyframes
15
+ * read the current value when their step starts.
15
16
  *
16
17
  * ```ts
17
18
  * await sequence([
@@ -1 +1 @@
1
- {"version":3,"file":"sequence.d.ts","sourceRoot":"","sources":["../src/sequence.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmC,KAAK,SAAS,EAAE,MAAM,aAAa,CAAA;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAEnE,MAAM,MAAM,IAAI,GACZ,SAAS;IACP,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE;IAClC,SAAS,EAAE,SAAS,GAAG,UAAU;IACjC,OAAO,CAAC,EAAE,cAAc,GAAG,UAAU;CACtC,GACD,CAAC,MAAM,SAAS,CAAC,CAAA;AAErB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,SAAS,CA8B1D"}
1
+ {"version":3,"file":"sequence.d.ts","sourceRoot":"","sources":["../src/sequence.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmC,KAAK,SAAS,EAAE,MAAM,aAAa,CAAA;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAEnE,MAAM,MAAM,IAAI,GACZ,SAAS;IACP,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE;IAClC,SAAS,EAAE,SAAS,GAAG,UAAU;IACjC,OAAO,CAAC,EAAE,cAAc,GAAG,UAAU;CACtC,GACD,CAAC,MAAM,SAAS,CAAC,CAAA;AAErB;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,SAAS,CA8B1D"}
package/dist/sequence.js CHANGED
@@ -4,8 +4,9 @@ import { writeValue } from './properties.js';
4
4
  /**
5
5
  * Plays steps one after the other. A step starts once the previous one looks
6
6
  * done: a spring is close to its target, even if it hasn't fully settled.
7
- * Views in later steps take their first keyframe right away, so a title that
8
- * fades in third doesn't show up before its turn.
7
+ * Views in later steps take their first absolute keyframe right away, so a title
8
+ * that fades in third doesn't show up before its turn. Relative and null keyframes
9
+ * read the current value when their step starts.
9
10
  *
10
11
  * ```ts
11
12
  * await sequence([
@@ -48,13 +49,13 @@ function applyStartingValues(steps) {
48
49
  for (const step of steps) {
49
50
  if (typeof step === 'function')
50
51
  continue;
51
- const [target, animation] = step;
52
- const starts = startingValues(animation);
52
+ const [target, animation, options] = step;
53
+ const starts = startingValues(animation, options);
53
54
  for (const view of toViews(target)) {
54
55
  let properties = claimed.get(view);
55
56
  if (!properties)
56
57
  claimed.set(view, (properties = new Set()));
57
- const fresh = [...starts].filter(([property]) => !properties.has(property));
58
+ const fresh = [...starts].filter(([property, value]) => !properties.has(property) && value !== null);
58
59
  stopView(view, fresh.map(([property]) => property));
59
60
  for (const [property, value] of fresh) {
60
61
  if (value !== null)
@@ -1 +1 @@
1
- {"version":3,"file":"sequence.js","sourceRoot":"","sources":["../src/sequence.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sequence.js","sourceRoot":"","sources":["../src/sequence.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -32,6 +32,8 @@ export interface Stagger {
32
32
  export type AnimateOptions = Transition & {
33
33
  [K in keyof Keyframes]?: Transition | SpringName;
34
34
  } & {
35
+ /** Offset translations/rotations and multiply scale/opacity by their values at the start. */
36
+ relative?: boolean;
35
37
  /** With several targets, delays each one by this much more than the previous. */
36
38
  stagger?: number | Stagger;
37
39
  };
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE7D,+GAA+G;AAC/G,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAA;AAE/D,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,qCAAqC;IACrC,CAAC,CAAC,EAAE,aAAa,CAAA;IACjB,qCAAqC;IACrC,CAAC,CAAC,EAAE,aAAa,CAAA;IACjB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,eAAe;IACf,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,OAAO,CAAC,EAAE,aAAa,CAAA;CACxB;AAED,+FAA+F;AAC/F,MAAM,MAAM,MAAM,GAChB,IAAI,GAAG;IAAE,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAA;CAAE,CAAA;AAEzE,MAAM,WAAW,OAAO;IACtB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ,iCAAiC;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;CAC5C;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG;KACvC,CAAC,IAAI,MAAM,SAAS,CAAC,CAAC,EAAE,UAAU,GAAG,UAAU;CACjD,GAAG;IACF,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAC3B,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE7D,+GAA+G;AAC/G,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAA;AAE/D,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,qCAAqC;IACrC,CAAC,CAAC,EAAE,aAAa,CAAA;IACjB,qCAAqC;IACrC,CAAC,CAAC,EAAE,aAAa,CAAA;IACjB,2CAA2C;IAC3C,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,eAAe;IACf,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,OAAO,CAAC,EAAE,aAAa,CAAA;CACxB;AAED,+FAA+F;AAC/F,MAAM,MAAM,MAAM,GAChB,IAAI,GAAG;IAAE,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAA;CAAE,CAAA;AAEzE,MAAM,WAAW,OAAO;IACtB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ,iCAAiC;IACjC,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;CAC5C;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG;KACvC,CAAC,IAAI,MAAM,SAAS,CAAC,CAAC,EAAE,UAAU,GAAG,UAAU;CACjD,GAAG;IACF,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAC3B,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rafaelaugusto/jolt",
3
- "version": "0.1.0-beta.0",
3
+ "version": "0.1.0-beta.1",
4
4
  "description": "Native animations for NativeScript: presets, springs, keyframes and stagger in one call.",
5
5
  "keywords": [
6
6
  "nativescript",
@@ -43,6 +43,9 @@
43
43
  "test:watch": "vitest",
44
44
  "format": "prettier --write .",
45
45
  "format:check": "prettier --check .",
46
+ "docs:dev": "vitepress dev docs",
47
+ "docs:build": "vitepress build docs",
48
+ "docs:preview": "vitepress preview docs",
46
49
  "prepack": "npm run build"
47
50
  },
48
51
  "peerDependencies": {
@@ -54,6 +57,7 @@
54
57
  "@nativescript/types-ios": "^9.1.3",
55
58
  "prettier": "^3.9.10",
56
59
  "typescript": "^7.0.2",
60
+ "vitepress": "^1.6.4",
57
61
  "vitest": "^5.0.4"
58
62
  },
59
63
  "engines": {
package/src/animate.ts CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  type Animation,
8
8
  type Plan,
9
9
  } from './engine.js'
10
- import { presets, type PresetName } from './presets.js'
10
+ import { getPreset, type PresetName } from './presets.js'
11
11
  import { isProperty, type Property } from './properties.js'
12
12
  import {
13
13
  hasCurve,
@@ -29,6 +29,7 @@ interface Options {
29
29
  base: Transition
30
30
  overrides: Partial<Record<keyof Keyframes, Transition>>
31
31
  stagger: number | Stagger | undefined
32
+ relative: boolean | undefined
32
33
  }
33
34
 
34
35
  /**
@@ -46,10 +47,13 @@ export function animate(
46
47
  animation: Keyframes | PresetName,
47
48
  options?: AnimateOptions | SpringName,
48
49
  ): Animation {
49
- const { keyframes, base, overrides, stagger } = prepare(animation, options)
50
+ const { keyframes, base, overrides, stagger, relative } = prepare(animation, options)
50
51
 
51
52
  if (!isList(target)) {
52
- return new ViewAnimation(toView(target), plan(keyframes, base, overrides, 0))
53
+ return new ViewAnimation(
54
+ toView(target),
55
+ plan(keyframes, base, overrides, 0, relative),
56
+ )
53
57
  }
54
58
 
55
59
  const views = target.map(toView)
@@ -58,15 +62,27 @@ export function animate(
58
62
  (view, index) =>
59
63
  new ViewAnimation(
60
64
  view,
61
- plan(keyframes, base, overrides, staggerDelay(stagger, index, views.length)),
65
+ plan(
66
+ keyframes,
67
+ base,
68
+ overrides,
69
+ staggerDelay(stagger, index, views.length),
70
+ relative,
71
+ ),
62
72
  ),
63
73
  ),
64
74
  )
65
75
  }
66
76
 
67
- /** Stops every animation running on the view, leaving it where it is. */
68
- export function stop(target: Target | readonly Target[]) {
69
- for (const view of toViews(target)) stopView(view)
77
+ /** Stops all or selected properties at their current values. `scale` stops both axes. */
78
+ export function stop(
79
+ target: Target | readonly Target[],
80
+ properties?: readonly (keyof Keyframes)[],
81
+ ) {
82
+ const expanded = properties?.flatMap<Property>((property) =>
83
+ property === 'scale' ? ['scaleX', 'scaleY'] : [property],
84
+ )
85
+ for (const view of toViews(target)) stopView(view, expanded)
70
86
  }
71
87
 
72
88
  /** Plays several animations as one: finished once they all are, and stopped together. */
@@ -107,35 +123,43 @@ function prepare(
107
123
  const user = normalize(options)
108
124
  if (typeof animation !== 'string') return { keyframes: animation, ...user }
109
125
 
110
- const preset = presets[animation]
111
- if (!preset) throw new Error(`Unknown preset "${animation}".`)
126
+ const preset = getPreset(animation)
112
127
  const own = normalize(preset.transition)
113
128
  return {
114
- keyframes: preset.keyframes as Keyframes,
129
+ keyframes: preset.keyframes,
115
130
  base: mergeTransitions(own.base, user.base),
116
131
  overrides: hasCurve(user.base)
117
132
  ? user.overrides
118
133
  : { ...own.overrides, ...user.overrides },
119
- stagger: user.stagger,
134
+ stagger: user.stagger ?? own.stagger,
135
+ relative: user.relative ?? own.relative,
120
136
  }
121
137
  }
122
138
 
123
139
  function normalize(options: AnimateOptions | SpringName | undefined): Options {
124
- if (options === undefined) return { base: {}, overrides: {}, stagger: undefined }
140
+ if (options === undefined)
141
+ return { base: {}, overrides: {}, stagger: undefined, relative: undefined }
125
142
  if (typeof options === 'string')
126
- return { base: spring(options), overrides: {}, stagger: undefined }
143
+ return {
144
+ base: spring(options),
145
+ overrides: {},
146
+ stagger: undefined,
147
+ relative: undefined,
148
+ }
127
149
 
128
150
  const base: Record<string, unknown> = {}
129
151
  const overrides: Options['overrides'] = {}
130
152
  let stagger: Options['stagger']
153
+ let relative: Options['relative']
131
154
  for (const [key, value] of Object.entries(options)) {
132
155
  if (value === undefined) continue
133
156
  if (key === 'stagger') stagger = value as Options['stagger']
157
+ else if (key === 'relative') relative = value as Options['relative']
134
158
  else if (key === 'scale' || isProperty(key)) {
135
159
  overrides[key] = typeof value === 'string' ? spring(value as SpringName) : value
136
160
  } else base[key] = value
137
161
  }
138
- return { base, overrides, stagger }
162
+ return { base, overrides, stagger, relative }
139
163
  }
140
164
 
141
165
  function plan(
@@ -143,6 +167,7 @@ function plan(
143
167
  base: Transition,
144
168
  overrides: Options['overrides'],
145
169
  offset: number,
170
+ relative = false,
146
171
  ): Plan[] {
147
172
  return expand(keyframes).map(([property, frames]) => {
148
173
  const override =
@@ -153,17 +178,19 @@ function plan(
153
178
  frames.length,
154
179
  )
155
180
  transition.delay += offset
156
- return { property, keyframes: frames, transition }
181
+ return { property, keyframes: frames, transition, relative }
157
182
  })
158
183
  }
159
184
 
160
185
  /** Each property the animation touches, with the value it starts from when it sets one. */
161
- export function startingValues(animation: Keyframes | PresetName) {
162
- const keyframes =
163
- typeof animation === 'string' ? presets[animation]?.keyframes : animation
186
+ export function startingValues(
187
+ animation: Keyframes | PresetName,
188
+ options?: AnimateOptions | SpringName,
189
+ ) {
190
+ const { keyframes, relative } = prepare(animation, options)
164
191
  if (!keyframes) throw new Error(`Unknown preset "${animation}".`)
165
192
  return new Map(
166
- expand(keyframes as Keyframes).map(([property, [first]]) => [property, first!]),
193
+ expand(keyframes).map(([property, [first]]) => [property, relative ? null : first!]),
167
194
  )
168
195
  }
169
196
 
package/src/driver/ios.ts CHANGED
@@ -5,6 +5,7 @@ import { after, type Driver } from './index.js'
5
5
  interface Handle {
6
6
  layers: CALayer[]
7
7
  key: string
8
+ onStop?: () => void
8
9
  }
9
10
 
10
11
  const keyPaths: Record<Property, string> = {
@@ -51,6 +52,7 @@ export function createIOSDriver(): Driver {
51
52
  const layers = layersOf(view)
52
53
  const key = `jolt:${track.property}`
53
54
  const rotation = track.property.startsWith('rotate')
55
+ const infinite = track.repeat === Infinity
54
56
  if (track.property === 'rotateX' || track.property === 'rotateY') {
55
57
  ensurePerspective(view, layers)
56
58
  }
@@ -63,22 +65,29 @@ export function createIOSDriver(): Driver {
63
65
  animation.duration = Math.max(track.duration, 1) / 1000
64
66
  animation.beginTime = (startedAt + track.delay) / 1000
65
67
  animation.fillMode = kCAFillModeBackwards
68
+ // Keep infinite loops when iOS removes animations on backgrounding.
69
+ // They are removed explicitly when stopped or replaced.
70
+ animation.removedOnCompletion = !infinite
66
71
  if (track.repeat > 0) {
67
72
  animation.autoreverses = track.reverse
68
73
  animation.repeatCount = track.reverse ? (track.repeat + 1) / 2 : track.repeat + 1
69
74
  }
70
75
 
71
76
  CATransaction.begin()
72
- CATransaction.setCompletionBlock(onEnd)
77
+ // iOS completes the transaction on backgrounding even if the loop is retained.
78
+ if (!infinite) CATransaction.setCompletionBlock(onEnd)
73
79
  for (const layer of layers) layer.addAnimationForKey(animation, key)
74
80
  CATransaction.commit()
75
81
 
76
- return { layers, key }
82
+ return { layers, key, onStop: infinite ? onEnd : undefined }
77
83
  },
78
84
 
79
85
  stop(_view, handle) {
80
- const { layers, key } = handle as Handle
86
+ const playing = handle as Handle
87
+ const { layers, key, onStop } = playing
88
+ playing.onStop = undefined
81
89
  for (const layer of layers) layer.removeAnimationForKey(key)
90
+ onStop?.()
82
91
  },
83
92
 
84
93
  presented: () => undefined,
package/src/engine.ts CHANGED
@@ -20,6 +20,7 @@ export interface Plan {
20
20
  /** `null` stands for the value the property has when the animation starts. */
21
21
  keyframes: readonly (number | null)[]
22
22
  transition: ResolvedTransition
23
+ relative?: boolean
23
24
  }
24
25
 
25
26
  interface Entry {
@@ -94,7 +95,7 @@ export class ViewAnimation implements Animation {
94
95
  const now = driver.now()
95
96
  const entries = entriesOf(this.view)
96
97
 
97
- const tracks = plans.map(({ property, keyframes, transition }) => {
98
+ const tracks = plans.map(({ property, keyframes, transition, relative }) => {
98
99
  const previous = entries.get(property)
99
100
  let current: number
100
101
  let velocity = 0
@@ -108,7 +109,13 @@ export class ViewAnimation implements Animation {
108
109
  }
109
110
  return createTrack(
110
111
  property,
111
- keyframes.map((value) => value ?? current),
112
+ keyframes.map((value) => {
113
+ if (value === null) return current
114
+ if (!relative) return value
115
+ return property === 'opacity' || property.startsWith('scale')
116
+ ? current * value
117
+ : current + value
118
+ }),
112
119
  transition,
113
120
  velocity,
114
121
  )
@@ -147,7 +154,8 @@ export class ViewAnimation implements Animation {
147
154
  }
148
155
 
149
156
  private waitForLoad(plans: readonly Plan[]) {
150
- for (const { property, keyframes } of plans) {
157
+ for (const { property, keyframes, relative } of plans) {
158
+ if (relative) continue
151
159
  const first = keyframes[0]
152
160
  if (first !== null && first !== undefined) writeValue(this.view, property, first)
153
161
  }
package/src/index.ts CHANGED
@@ -2,8 +2,8 @@ export { animate, stop } from './animate.js'
2
2
  export { sequence } from './sequence.js'
3
3
  export type { Step } from './sequence.js'
4
4
  export { press } from './press.js'
5
- export { presets } from './presets.js'
6
- export type { PresetName } from './presets.js'
5
+ export { definePreset, presets } from './presets.js'
6
+ export type { Preset, PresetName, Presets } from './presets.js'
7
7
  export { springs } from './transition.js'
8
8
  export type { Spring, SpringName, Timing, Transition, Tween } from './transition.js'
9
9
  export { cubicBezier } from './easing.js'
package/src/presets.ts CHANGED
@@ -5,6 +5,9 @@ export interface Preset {
5
5
  transition: AnimateOptions
6
6
  }
7
7
 
8
+ /** Add custom preset names through module augmentation, with `true` as each value. */
9
+ export interface Presets {}
10
+
8
11
  const fadeIn = { duration: 300, ease: 'easeOut' } as const
9
12
  const fadeOut = { duration: 200, ease: 'easeIn' } as const
10
13
  const enter = { type: 'spring', duration: 500, bounce: 0 } as const
@@ -77,28 +80,30 @@ export const presets = {
77
80
 
78
81
  pulse: {
79
82
  keyframes: { scale: [1, 1.06, 1] },
80
- transition: { duration: 500, ease: 'easeInOut' },
83
+ transition: { duration: 500, ease: 'easeInOut', relative: true },
81
84
  },
82
85
  bounce: {
83
86
  keyframes: { y: [0, -18, 0, -8, 0] },
84
87
  transition: {
85
88
  duration: 650,
89
+ relative: true,
86
90
  times: [0, 0.3, 0.6, 0.8, 1],
87
91
  ease: ['easeOut', 'easeIn', 'easeOut', 'easeIn'],
88
92
  },
89
93
  },
90
94
  shake: {
91
95
  keyframes: { x: [0, -10, 10, -8, 8, -4, 4, 0] },
92
- transition: { duration: 500, ease: 'easeInOut' },
96
+ transition: { duration: 500, ease: 'easeInOut', relative: true },
93
97
  },
94
98
  wiggle: {
95
99
  keyframes: { rotate: [0, -8, 8, -5, 5, 0] },
96
- transition: { duration: 500, ease: 'easeInOut' },
100
+ transition: { duration: 500, ease: 'easeInOut', relative: true },
97
101
  },
98
102
  heartbeat: {
99
103
  keyframes: { scale: [1, 1.15, 1, 1.15, 1, 1] },
100
104
  transition: {
101
105
  duration: 1000,
106
+ relative: true,
102
107
  times: [0, 0.14, 0.28, 0.42, 0.7, 1],
103
108
  ease: 'easeInOut',
104
109
  },
@@ -110,25 +115,44 @@ export const presets = {
110
115
  },
111
116
  transition: {
112
117
  duration: 800,
118
+ relative: true,
113
119
  times: [0, 0.3, 0.4, 0.5, 0.65, 0.75, 1],
114
120
  ease: 'easeInOut',
115
121
  },
116
122
  },
117
123
  flash: {
118
124
  keyframes: { opacity: [1, 0, 1, 0, 1] },
119
- transition: { duration: 800, ease: 'easeInOut' },
125
+ transition: { duration: 800, ease: 'easeInOut', relative: true },
120
126
  },
121
127
  tada: {
122
128
  keyframes: {
123
129
  scale: [1, 0.9, 0.9, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1.1, 1],
124
130
  rotate: [0, -3, -3, 3, -3, 3, -3, 3, -3, 3, 0],
125
131
  },
126
- transition: { duration: 1000, ease: 'easeInOut' },
132
+ transition: { duration: 1000, ease: 'easeInOut', relative: true },
127
133
  },
128
134
  spin: {
129
135
  keyframes: { rotate: [0, 360] },
130
- transition: { duration: 1000, ease: 'linear' },
136
+ transition: { duration: 1000, ease: 'linear', relative: true },
131
137
  },
132
138
  } satisfies Record<string, Preset>
133
139
 
134
- export type PresetName = keyof typeof presets
140
+ export type PresetName = keyof typeof presets | Extract<keyof Presets, string>
141
+
142
+ const customPresets = new Map<string, Preset>()
143
+
144
+ /** Registers a custom preset. Registering it again replaces it for future animations. */
145
+ export function definePreset(name: PresetName, preset: Preset): void {
146
+ if (Object.hasOwn(presets, name)) {
147
+ throw new Error(`Preset "${name}" is built in and cannot be replaced.`)
148
+ }
149
+ customPresets.set(name, preset)
150
+ }
151
+
152
+ export function getPreset(name: PresetName): Preset {
153
+ const preset =
154
+ customPresets.get(name) ??
155
+ (Object.hasOwn(presets, name) ? presets[name as keyof typeof presets] : undefined)
156
+ if (!preset) throw new Error(`Unknown preset "${name}".`)
157
+ return preset
158
+ }
package/src/press.ts CHANGED
@@ -33,7 +33,13 @@ export function press(
33
33
  rest = Object.fromEntries(properties.map((p) => [p, readValue(view, p)]))
34
34
  animate(view, pressed, options ?? pressIn)
35
35
  } else if ((action === 'up' || action === 'cancel') && rest) {
36
- animate(view, rest, options ?? release)
36
+ animate(
37
+ view,
38
+ rest,
39
+ typeof options === 'object'
40
+ ? { ...options, relative: false }
41
+ : (options ?? release),
42
+ )
37
43
  rest = undefined
38
44
  }
39
45
  }
package/src/sequence.ts CHANGED
@@ -17,8 +17,9 @@ export type Step =
17
17
  /**
18
18
  * Plays steps one after the other. A step starts once the previous one looks
19
19
  * done: a spring is close to its target, even if it hasn't fully settled.
20
- * Views in later steps take their first keyframe right away, so a title that
21
- * fades in third doesn't show up before its turn.
20
+ * Views in later steps take their first absolute keyframe right away, so a title
21
+ * that fades in third doesn't show up before its turn. Relative and null keyframes
22
+ * read the current value when their step starts.
22
23
  *
23
24
  * ```ts
24
25
  * await sequence([
@@ -64,14 +65,16 @@ function applyStartingValues(steps: readonly Step[]) {
64
65
  const claimed = new Map<View, Set<Property>>()
65
66
  for (const step of steps) {
66
67
  if (typeof step === 'function') continue
67
- const [target, animation] = step
68
- const starts = startingValues(animation)
68
+ const [target, animation, options] = step
69
+ const starts = startingValues(animation, options)
69
70
 
70
71
  for (const view of toViews(target)) {
71
72
  let properties = claimed.get(view)
72
73
  if (!properties) claimed.set(view, (properties = new Set()))
73
74
 
74
- const fresh = [...starts].filter(([property]) => !properties.has(property))
75
+ const fresh = [...starts].filter(
76
+ ([property, value]) => !properties.has(property) && value !== null,
77
+ )
75
78
  stopView(
76
79
  view,
77
80
  fresh.map(([property]) => property),
package/src/types.ts CHANGED
@@ -34,6 +34,8 @@ export interface Stagger {
34
34
  export type AnimateOptions = Transition & {
35
35
  [K in keyof Keyframes]?: Transition | SpringName
36
36
  } & {
37
+ /** Offset translations/rotations and multiply scale/opacity by their values at the start. */
38
+ relative?: boolean
37
39
  /** With several targets, delays each one by this much more than the previous. */
38
40
  stagger?: number | Stagger
39
41
  }