@xtia/timeline 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -163,7 +163,8 @@ Tween emitters can interpolate numbers, arrays of numbers, strings, and objects
163
163
  * Otherwise the `from` string is progressively replaced, left-to-right, with the `to` string
164
164
 
165
165
  ```ts
166
- // note: this looks really cool
166
+ // tween four values in a CSS string
167
+ // see this live: https://codepen.io/xtaltia/pen/PwZYbKY
167
168
  timeline
168
169
  .range(0, 2000)
169
170
  .ease("elastic")
@@ -1,14 +1,15 @@
1
1
  import { Easer, easers } from "./easing";
2
2
  import { Blendable } from "./tween";
3
3
  /** @internal */
4
- export declare function createEmitter<T>(onListen: (handler: Handler<T>) => UnsubscribeFunc): Emitter<T>;
4
+ export declare function createEmitter<T>(listen: ListenFunc<T>): Emitter<T>;
5
5
  /** @internal */
6
- export declare function createEmitter<T, API extends object>(onListen: (handler: Handler<T>) => UnsubscribeFunc, api: Omit<API, keyof Emitter<T>>): Emitter<T> & API;
6
+ export declare function createEmitter<T, API extends object>(onListen: ListenFunc<T>, api: Omit<API, keyof Emitter<T>>): Emitter<T> & API;
7
7
  /** @internal */
8
- export declare function createProgressEmitter<API extends object>(onListen: (handler: Handler<number>) => UnsubscribeFunc, api: Omit<API, keyof RangeProgression>): RangeProgression & API;
8
+ export declare function createProgressEmitter<API extends object>(onListen: ListenFunc<number>, api: Omit<API, keyof RangeProgression>): RangeProgression & API;
9
9
  /** @internal */
10
- export declare function createProgressEmitter(onListen: (handler: Handler<number>) => UnsubscribeFunc): RangeProgression;
10
+ export declare function createProgressEmitter(onListen: ListenFunc<number>): RangeProgression;
11
11
  type Handler<T> = (value: T) => void;
12
+ type ListenFunc<T> = (handler: Handler<T>) => UnsubscribeFunc;
12
13
  export type UnsubscribeFunc = () => void;
13
14
  export interface Emitter<T> {
14
15
  /**
@@ -149,5 +150,22 @@ export interface RangeProgression extends Emitter<number> {
149
150
  * @returns Listenable: emits non-repeating values
150
151
  */
151
152
  noRepeat(): RangeProgression;
153
+ /**
154
+ * Creates a chainable progress emitter that offsets its parent's values by the given delta, wrapping between 0 and 1
155
+ *
156
+ * ```plain
157
+ *‎ 1
158
+ *‎ | /
159
+ *‎ o| /
160
+ *‎ u|/ __ delta=.5
161
+ *‎ t| /
162
+ *‎ | /
163
+ *‎ |___/__
164
+ *‎ 0 in 1
165
+ * ```
166
+ *
167
+ * @param delta
168
+ */
169
+ offset(delta: number): RangeProgression;
152
170
  }
153
171
  export {};
@@ -5,16 +5,15 @@ exports.createProgressEmitter = createProgressEmitter;
5
5
  const easing_1 = require("./easing");
6
6
  const tween_1 = require("./tween");
7
7
  const utils_1 = require("./utils");
8
- /** @internal */
9
- function createEmitter(onListen, api) {
10
- const propertyDescriptor = Object.fromEntries(Object.entries({
11
- listen: (handler) => onListen((value) => {
8
+ function createEmitterMethodProperties(listen, extensions) {
9
+ return Object.fromEntries(Object.entries({
10
+ listen: (handler) => listen((value) => {
12
11
  handler(value);
13
12
  }),
14
- map: (mapFunc) => createEmitter(handler => onListen((value) => {
13
+ map: (mapFunc) => createEmitter(handler => listen((value) => {
15
14
  handler(mapFunc(value));
16
15
  })),
17
- filter: (filterFunc) => createEmitter(handler => onListen((value) => {
16
+ filter: (filterFunc) => createEmitter(handler => listen((value) => {
18
17
  if (filterFunc(value))
19
18
  handler(value);
20
19
  })),
@@ -29,57 +28,62 @@ function createEmitter(onListen, api) {
29
28
  previous = { value };
30
29
  }
31
30
  };
32
- return onListen(filteredHandler);
31
+ return listen(filteredHandler);
33
32
  });
34
33
  },
35
- tap: (cb) => createEmitter(createTapListener(cb, onListen)),
34
+ tap: (cb) => createTap(cb, createEmitter, listen),
35
+ ...extensions,
36
36
  }).map(([key, value]) => [
37
37
  key,
38
38
  { value }
39
39
  ]));
40
+ }
41
+ /** @internal */
42
+ function createEmitter(listen, api) {
43
+ const propertyDescriptor = createEmitterMethodProperties(listen, {});
40
44
  return Object.create(api ?? {}, propertyDescriptor);
41
45
  }
42
46
  /** @internal */
43
- function createProgressEmitter(onListen, api = {}) {
44
- const propertyDescriptor = Object.fromEntries(Object.entries({
47
+ function createProgressEmitter(listen, api = {}) {
48
+ const propertyDescriptor = createEmitterMethodProperties(listen, {
45
49
  ease: (easer) => {
46
50
  const easerFunc = typeof easer == "string"
47
51
  ? easing_1.easers[easer]
48
52
  : easer;
49
- return createProgressEmitter(easer ? (handler => onListen((progress) => {
53
+ return createProgressEmitter(easer ? (handler => listen((progress) => {
50
54
  handler(easerFunc(progress));
51
- })) : onListen);
55
+ })) : listen);
52
56
  },
53
- tween: (from, to) => createEmitter(handler => onListen(progress => handler((0, tween_1.tweenValue)(from, to, progress)))),
57
+ tween: (from, to) => createEmitter(handler => listen(progress => handler((0, tween_1.tweenValue)(from, to, progress)))),
54
58
  snap: (steps) => {
55
59
  if (!Number.isInteger(steps) || steps <= 0) {
56
60
  throw new RangeError('snap(steps) requires a positive integer');
57
61
  }
58
- return createProgressEmitter(handler => onListen(progress => {
62
+ return createProgressEmitter(handler => listen(progress => {
59
63
  const snapped = Math.round(progress * steps) / steps;
60
64
  handler((0, utils_1.clamp)(snapped, 0, 1));
61
65
  }));
62
66
  },
63
- threshold: (threshold) => createProgressEmitter(handler => onListen(progress => {
67
+ threshold: (threshold) => createProgressEmitter(handler => listen(progress => {
64
68
  handler(progress >= threshold ? 1 : 0);
65
69
  })),
66
- clamp: (min = 0, max = 1) => createProgressEmitter(handler => onListen(progress => handler((0, utils_1.clamp)(progress, min, max)))),
70
+ clamp: (min = 0, max = 1) => createProgressEmitter(handler => listen(progress => handler((0, utils_1.clamp)(progress, min, max)))),
67
71
  repeat: (repetitions) => {
68
72
  repetitions = Math.max(0, repetitions);
69
- return createProgressEmitter(handler => onListen(progress => {
73
+ return createProgressEmitter(handler => listen(progress => {
70
74
  const out = (progress * repetitions) % 1;
71
75
  handler(out);
72
76
  }));
73
77
  },
74
- tap: (cb) => createProgressEmitter(createTapListener(cb, onListen)),
75
- filter: (filterFunc) => createProgressEmitter(handler => onListen((value) => {
78
+ tap: (cb) => createTap(cb, createProgressEmitter, listen),
79
+ filter: (filterFunc) => createProgressEmitter(handler => listen((value) => {
76
80
  if (filterFunc(value))
77
81
  handler(value);
78
82
  })),
79
83
  noRepeat: () => {
80
84
  let previous = null;
81
85
  return createProgressEmitter(handler => {
82
- return onListen((value) => {
86
+ return listen((value) => {
83
87
  if (!previous || (previous.value !== value)) {
84
88
  handler(value);
85
89
  previous = { value };
@@ -87,19 +91,17 @@ function createProgressEmitter(onListen, api = {}) {
87
91
  });
88
92
  });
89
93
  },
90
- }).map(([key, value]) => [
91
- key,
92
- { value }
93
- ]));
94
- return createEmitter(onListen, Object.create(api, propertyDescriptor));
94
+ offset: (delta) => createProgressEmitter(handler => listen(value => handler((value + delta) % 1))),
95
+ });
96
+ return Object.create(api ?? {}, propertyDescriptor);
95
97
  }
96
- function createTapListener(callback, parentOnListen) {
98
+ function createTap(callback, create, parentListen) {
97
99
  const listeners = [];
98
100
  let parentUnsubscribe = null;
99
101
  const tapOnListen = (handler) => {
100
102
  listeners.push(handler);
101
103
  if (listeners.length === 1) {
102
- parentUnsubscribe = parentOnListen(value => {
104
+ parentUnsubscribe = parentListen(value => {
103
105
  callback(value);
104
106
  listeners.slice().forEach(fn => fn(value));
105
107
  });
@@ -113,5 +115,5 @@ function createTapListener(callback, parentOnListen) {
113
115
  }
114
116
  };
115
117
  };
116
- return tapOnListen;
118
+ return create(tapOnListen);
117
119
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xtia/timeline",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "repository": {
5
5
  "url": "https://github.com/tiadrop/timeline",
6
6
  "type": "github"