chnobli 0.1.7 → 0.1.9

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.
Files changed (225) hide show
  1. package/package.json +24 -11
  2. package/src/animation/Animation.ts +10 -6
  3. package/src/animation/public.ts +47 -10
  4. package/src/chnobli.ts +20 -11
  5. package/src/property/BasicProperty.ts +3 -3
  6. package/src/property/ClassProperty.ts +2 -2
  7. package/src/property/Property.ts +7 -5
  8. package/src/property/StyleProperty.ts +7 -7
  9. package/src/property/TransformProperty.ts +4 -4
  10. package/src/property/TransformXYProperty.ts +3 -3
  11. package/src/responsive/TestEvent.ts +1 -1
  12. package/src/scroll/Scroll.ts +174 -90
  13. package/src/scroll/index.ts +8 -0
  14. package/src/scroll/public.ts +23 -12
  15. package/src/stagger/stagger.ts +34 -14
  16. package/src/target/BaseTarget.old.ts +2 -2
  17. package/src/target/DomTarget.ts +3 -3
  18. package/src/target/ObjectTarget.ts +124 -0
  19. package/src/target/Target.ts +16 -3
  20. package/src/tests/properties.test.ts +54 -4
  21. package/src/tests/timeline.test.ts +3 -3
  22. package/src/tests/timing.test.ts +1 -1
  23. package/src/tests/usecases.test.ts +5 -5
  24. package/src/tests/values.test.ts +4 -4
  25. package/src/timeline/Nested.ts +7 -7
  26. package/src/timeline/{TimeLine.ts → Timeline.ts} +29 -9
  27. package/src/timeline/public.ts +198 -58
  28. package/src/timing/AnimationFrameTicker.ts +2 -2
  29. package/src/timing/TestTicker.ts +2 -2
  30. package/src/timing/Ticker.ts +1 -1
  31. package/src/timing/Timing.ts +38 -4
  32. package/src/utils/internal.ts +6 -3
  33. package/src/utils/utils.ts +18 -9
  34. package/src/values/ColorValue.ts +1 -1
  35. package/src/values/StyleValue.ts +15 -3
  36. package/tsconfig.build.json +2 -2
  37. package/tsconfig.json +2 -3
  38. package/.editorconfig +0 -11
  39. package/.github/workflows/ci.yaml +0 -34
  40. package/.prettierignore +0 -4
  41. package/.prettierrc +0 -6
  42. package/.vscode/settings.json +0 -4
  43. package/LICENSE.md +0 -21
  44. package/README.md +0 -5
  45. package/auto-docs/easing.js.html +0 -342
  46. package/auto-docs/fonts/OpenSans-Bold-webfont.eot +0 -0
  47. package/auto-docs/fonts/OpenSans-Bold-webfont.svg +0 -1830
  48. package/auto-docs/fonts/OpenSans-Bold-webfont.woff +0 -0
  49. package/auto-docs/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
  50. package/auto-docs/fonts/OpenSans-BoldItalic-webfont.svg +0 -1830
  51. package/auto-docs/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
  52. package/auto-docs/fonts/OpenSans-Italic-webfont.eot +0 -0
  53. package/auto-docs/fonts/OpenSans-Italic-webfont.svg +0 -1830
  54. package/auto-docs/fonts/OpenSans-Italic-webfont.woff +0 -0
  55. package/auto-docs/fonts/OpenSans-Light-webfont.eot +0 -0
  56. package/auto-docs/fonts/OpenSans-Light-webfont.svg +0 -1831
  57. package/auto-docs/fonts/OpenSans-Light-webfont.woff +0 -0
  58. package/auto-docs/fonts/OpenSans-LightItalic-webfont.eot +0 -0
  59. package/auto-docs/fonts/OpenSans-LightItalic-webfont.svg +0 -1835
  60. package/auto-docs/fonts/OpenSans-LightItalic-webfont.woff +0 -0
  61. package/auto-docs/fonts/OpenSans-Regular-webfont.eot +0 -0
  62. package/auto-docs/fonts/OpenSans-Regular-webfont.svg +0 -1831
  63. package/auto-docs/fonts/OpenSans-Regular-webfont.woff +0 -0
  64. package/auto-docs/global.html +0 -4810
  65. package/auto-docs/index.html +0 -65
  66. package/auto-docs/scripts/linenumber.js +0 -25
  67. package/auto-docs/scripts/prettify/Apache-License-2.0.txt +0 -202
  68. package/auto-docs/scripts/prettify/lang-css.js +0 -2
  69. package/auto-docs/scripts/prettify/prettify.js +0 -28
  70. package/auto-docs/styles/jsdoc-default.css +0 -358
  71. package/auto-docs/styles/prettify-jsdoc.css +0 -111
  72. package/auto-docs/styles/prettify-tomorrow.css +0 -132
  73. package/dist/animation/Animation.d.ts +0 -36
  74. package/dist/animation/Animation.d.ts.map +0 -1
  75. package/dist/animation/Animation.js +0 -230
  76. package/dist/animation/Animation.js.map +0 -1
  77. package/dist/animation/animation.d.ts +0 -36
  78. package/dist/animation/animation.d.ts.map +0 -1
  79. package/dist/animation/animation.js +0 -230
  80. package/dist/animation/animation.js.map +0 -1
  81. package/dist/animation/public.d.ts +0 -55
  82. package/dist/animation/public.d.ts.map +0 -1
  83. package/dist/animation/public.js +0 -104
  84. package/dist/animation/public.js.map +0 -1
  85. package/dist/chnobli.d.ts +0 -15
  86. package/dist/chnobli.d.ts.map +0 -1
  87. package/dist/chnobli.js +0 -63
  88. package/dist/chnobli.js.map +0 -1
  89. package/dist/property/BasicProperty.d.ts +0 -38
  90. package/dist/property/BasicProperty.d.ts.map +0 -1
  91. package/dist/property/BasicProperty.js +0 -72
  92. package/dist/property/BasicProperty.js.map +0 -1
  93. package/dist/property/ClassProperty.d.ts +0 -32
  94. package/dist/property/ClassProperty.d.ts.map +0 -1
  95. package/dist/property/ClassProperty.js +0 -108
  96. package/dist/property/ClassProperty.js.map +0 -1
  97. package/dist/property/Property.d.ts +0 -13
  98. package/dist/property/Property.d.ts.map +0 -1
  99. package/dist/property/Property.js +0 -20
  100. package/dist/property/Property.js.map +0 -1
  101. package/dist/property/StyleProperty.d.ts +0 -25
  102. package/dist/property/StyleProperty.d.ts.map +0 -1
  103. package/dist/property/StyleProperty.js +0 -221
  104. package/dist/property/StyleProperty.js.map +0 -1
  105. package/dist/property/TransformProperty.d.ts +0 -15
  106. package/dist/property/TransformProperty.d.ts.map +0 -1
  107. package/dist/property/TransformProperty.js +0 -43
  108. package/dist/property/TransformProperty.js.map +0 -1
  109. package/dist/property/TransformXYProperty.d.ts +0 -28
  110. package/dist/property/TransformXYProperty.d.ts.map +0 -1
  111. package/dist/property/TransformXYProperty.js +0 -65
  112. package/dist/property/TransformXYProperty.js.map +0 -1
  113. package/dist/responsive/ResponsiveEvent.d.ts +0 -17
  114. package/dist/responsive/ResponsiveEvent.d.ts.map +0 -1
  115. package/dist/responsive/ResponsiveEvent.js +0 -45
  116. package/dist/responsive/ResponsiveEvent.js.map +0 -1
  117. package/dist/responsive/TestEvent.d.ts +0 -11
  118. package/dist/responsive/TestEvent.d.ts.map +0 -1
  119. package/dist/responsive/TestEvent.js +0 -26
  120. package/dist/responsive/TestEvent.js.map +0 -1
  121. package/dist/responsive/event.d.ts +0 -10
  122. package/dist/responsive/event.d.ts.map +0 -1
  123. package/dist/responsive/event.js +0 -39
  124. package/dist/responsive/event.js.map +0 -1
  125. package/dist/scroll/Scroll.d.ts +0 -27
  126. package/dist/scroll/Scroll.d.ts.map +0 -1
  127. package/dist/scroll/Scroll.js +0 -132
  128. package/dist/scroll/Scroll.js.map +0 -1
  129. package/dist/scroll/ScrollEvent.d.ts +0 -17
  130. package/dist/scroll/ScrollEvent.d.ts.map +0 -1
  131. package/dist/scroll/ScrollEvent.js +0 -39
  132. package/dist/scroll/ScrollEvent.js.map +0 -1
  133. package/dist/scroll/public.d.ts +0 -7
  134. package/dist/scroll/public.d.ts.map +0 -1
  135. package/dist/scroll/public.js +0 -17
  136. package/dist/scroll/public.js.map +0 -1
  137. package/dist/stagger/stagger.d.ts +0 -13
  138. package/dist/stagger/stagger.d.ts.map +0 -1
  139. package/dist/stagger/stagger.js +0 -35
  140. package/dist/stagger/stagger.js.map +0 -1
  141. package/dist/target/BaseTarget.old.d.ts +0 -33
  142. package/dist/target/BaseTarget.old.d.ts.map +0 -1
  143. package/dist/target/BaseTarget.old.js +0 -73
  144. package/dist/target/BaseTarget.old.js.map +0 -1
  145. package/dist/target/DomTarget.d.ts +0 -41
  146. package/dist/target/DomTarget.d.ts.map +0 -1
  147. package/dist/target/DomTarget.js +0 -230
  148. package/dist/target/DomTarget.js.map +0 -1
  149. package/dist/target/Target.d.ts +0 -22
  150. package/dist/target/Target.d.ts.map +0 -1
  151. package/dist/target/Target.js +0 -21
  152. package/dist/target/Target.js.map +0 -1
  153. package/dist/target/TestDomNode.d.ts +0 -14
  154. package/dist/target/TestDomNode.d.ts.map +0 -1
  155. package/dist/target/TestDomNode.js +0 -55
  156. package/dist/target/TestDomNode.js.map +0 -1
  157. package/dist/timeline/Nested.d.ts +0 -30
  158. package/dist/timeline/Nested.d.ts.map +0 -1
  159. package/dist/timeline/Nested.js +0 -51
  160. package/dist/timeline/Nested.js.map +0 -1
  161. package/dist/timeline/TimeLine.d.ts +0 -32
  162. package/dist/timeline/TimeLine.d.ts.map +0 -1
  163. package/dist/timeline/TimeLine.js +0 -288
  164. package/dist/timeline/TimeLine.js.map +0 -1
  165. package/dist/timeline/public.d.ts +0 -120
  166. package/dist/timeline/public.d.ts.map +0 -1
  167. package/dist/timeline/public.js +0 -301
  168. package/dist/timeline/public.js.map +0 -1
  169. package/dist/timing/AnimationFrameTicker.d.ts +0 -32
  170. package/dist/timing/AnimationFrameTicker.d.ts.map +0 -1
  171. package/dist/timing/AnimationFrameTicker.js +0 -134
  172. package/dist/timing/AnimationFrameTicker.js.map +0 -1
  173. package/dist/timing/Ease.d.ts +0 -6
  174. package/dist/timing/Ease.d.ts.map +0 -1
  175. package/dist/timing/Ease.js +0 -15
  176. package/dist/timing/Ease.js.map +0 -1
  177. package/dist/timing/TestTicker.d.ts +0 -19
  178. package/dist/timing/TestTicker.d.ts.map +0 -1
  179. package/dist/timing/TestTicker.js +0 -81
  180. package/dist/timing/TestTicker.js.map +0 -1
  181. package/dist/timing/Ticker.d.ts +0 -14
  182. package/dist/timing/Ticker.d.ts.map +0 -1
  183. package/dist/timing/Ticker.js +0 -2
  184. package/dist/timing/Ticker.js.map +0 -1
  185. package/dist/timing/Timing.d.ts +0 -62
  186. package/dist/timing/Timing.d.ts.map +0 -1
  187. package/dist/timing/Timing.js +0 -257
  188. package/dist/timing/Timing.js.map +0 -1
  189. package/dist/timing/easing.d.ts +0 -158
  190. package/dist/timing/easing.d.ts.map +0 -1
  191. package/dist/timing/easing.js +0 -273
  192. package/dist/timing/easing.js.map +0 -1
  193. package/dist/utils/Events.d.ts +0 -9
  194. package/dist/utils/Events.d.ts.map +0 -1
  195. package/dist/utils/Events.js +0 -35
  196. package/dist/utils/Events.js.map +0 -1
  197. package/dist/utils/internal.d.ts +0 -2
  198. package/dist/utils/internal.d.ts.map +0 -1
  199. package/dist/utils/internal.js +0 -6
  200. package/dist/utils/internal.js.map +0 -1
  201. package/dist/utils/motionpath.d.ts +0 -16
  202. package/dist/utils/motionpath.d.ts.map +0 -1
  203. package/dist/utils/motionpath.js +0 -41
  204. package/dist/utils/motionpath.js.map +0 -1
  205. package/dist/utils/utils.d.ts +0 -43
  206. package/dist/utils/utils.d.ts.map +0 -1
  207. package/dist/utils/utils.js +0 -93
  208. package/dist/utils/utils.js.map +0 -1
  209. package/dist/values/ColorValue.d.ts +0 -12
  210. package/dist/values/ColorValue.d.ts.map +0 -1
  211. package/dist/values/ColorValue.js +0 -133
  212. package/dist/values/ColorValue.js.map +0 -1
  213. package/dist/values/StyleValue.d.ts +0 -40
  214. package/dist/values/StyleValue.d.ts.map +0 -1
  215. package/dist/values/StyleValue.js +0 -149
  216. package/dist/values/StyleValue.js.map +0 -1
  217. package/dist/values/Value.d.ts +0 -13
  218. package/dist/values/Value.d.ts.map +0 -1
  219. package/dist/values/Value.js +0 -38
  220. package/dist/values/Value.js.map +0 -1
  221. package/dist/values/defaultcolors.d.ts +0 -2
  222. package/dist/values/defaultcolors.d.ts.map +0 -1
  223. package/dist/values/defaultcolors.js +0 -149
  224. package/dist/values/defaultcolors.js.map +0 -1
  225. package/docs/INDEX.md +0 -15
@@ -1,9 +1,29 @@
1
- import PublicTimeline from '../timeline/public';
2
- import { takeProp } from '../utils/internal';
3
- import { pageOffset } from '../utils/utils';
4
- import ScrollEvent from './ScrollEvent';
1
+ import PublicTimeline, { Offset } from '../timeline/public.js';
2
+ import { pageOffset } from '../utils/utils.js';
3
+ import ScrollEvent from './ScrollEvent.js';
5
4
 
6
5
  /*
6
+ run timelines based on the scroll position
7
+
8
+ scroll allows to specify a start and end trigger
9
+ which then makes sure the timeline is always in sync with
10
+ the scroll position
11
+
12
+ {
13
+ start: myDiv,
14
+ // when the top of myDiv is at the top of the viewport
15
+ end: {
16
+ target: myDiv,
17
+ offset: 'bottom',
18
+ view: 'bottom'
19
+ }
20
+ // when the bottom of myDiv is at the bottom of the viewport
21
+ }
22
+
23
+
24
+
25
+
26
+
7
27
  run animation when in view (start stop resume when different events happen)
8
28
 
9
29
 
@@ -24,57 +44,76 @@ scroll pin (once in trigger zone, elements keeps it position relative to start o
24
44
  parallax
25
45
  */
26
46
 
27
- type StartEndOffset = {
47
+ export type ScrollTrigger =
48
+ | {
49
+ target: HTMLElement;
50
+ offset?: OffsetValue;
51
+ view?: OffsetValue;
52
+ }
53
+ | HTMLElement;
54
+
55
+ export type OffsetValue = 'top' | 'center' | 'bottom' | number;
56
+
57
+ export type ParsedScrollTrigger = {
28
58
  target: HTMLElement;
29
59
  offset: number;
30
- };
31
-
32
- export type Start = {
33
- y: number;
34
60
  view: number;
61
+ position: Position;
35
62
  };
36
63
 
37
- export type End = {
64
+ export type ScrollOffset = {
65
+ // the offset in pixels
38
66
  y: number;
67
+ // the offset in percentage (0-1)
39
68
  view: number;
69
+ // position
70
+ position: number;
40
71
  };
41
72
 
42
- export default class Scroll {
43
- private _start: StartEndOffset;
44
- private _end: StartEndOffset | null;
45
- private _globalEvent: ScrollEvent;
73
+ export type Position = number | string;
46
74
 
47
- start: Start;
48
- end: End;
75
+ export default class ScrollTimeline {
76
+ private _initialized: boolean;
77
+ private _globalEvent: ScrollEvent;
78
+ private _rmEvent: () => void;
49
79
 
80
+ private _triggers: ParsedScrollTrigger[];
50
81
  private timelines: PublicTimeline[];
51
- private _rmEvent: () => void;
52
- private _initialized: boolean;
82
+ offsets: ScrollOffset[];
53
83
 
54
- constructor(props = {}) {
55
- // { target, offset }
56
- this._start = parseStart(takeProp(props, 'start', null));
57
- // { target, offset }
58
- this._end = parseEnd(takeProp(props, 'end', null));
84
+ constructor() {
85
+ this._initialized = false;
59
86
  this._globalEvent = ScrollEvent.global();
87
+ this._rmEvent = this._globalEvent.add(y => this._onScroll(y)).remove;
60
88
 
61
- this.start = {
62
- // px
63
- y: 0,
64
- // percentage
65
- view: parseOffset(takeProp(props, 'startView', 'top')),
66
- };
67
- this.end = {
68
- // px
69
- y: 0,
70
- // percentage
71
- view: parseOffset(takeProp(props, 'endView', 'bottom')),
72
- };
73
-
89
+ this._triggers = [];
74
90
  this.timelines = [];
91
+ this.offsets = [];
92
+
93
+ // this.timeline = timeline;
94
+ // this._triggers = triggers.map(parseTrigger);
95
+ // this.offsets = this._triggers.map(t => {
96
+ // return {
97
+ // y: 0,
98
+ // view: t.view,
99
+ // };
100
+ // });
101
+
102
+ // if (this.offsets.length < 2)
103
+ // throw new Error('scroll timeline needs at least two triggers');
104
+ }
75
105
 
76
- this._rmEvent = this._globalEvent.add(y => this._onScroll(y)).remove;
77
- this._initialized = false;
106
+ /**
107
+ * Add a trigger to the timeline
108
+ *
109
+ * Providing an offset at which point the trigger should end
110
+ *
111
+ * If it is the first trigger it is not allowed to be set?
112
+ */
113
+ add(trigger: ScrollTrigger, position?: Position) {
114
+ this._triggers.push(
115
+ parseTrigger(trigger, position, this._triggers.length),
116
+ );
78
117
  }
79
118
 
80
119
  addTimeline(timeline: PublicTimeline) {
@@ -82,77 +121,113 @@ export default class Scroll {
82
121
  }
83
122
 
84
123
  init() {
85
- const startOffset = pageOffset(this._start.target);
86
- this.start.y =
87
- startOffset.top + startOffset.height * this._start.offset;
88
-
89
- if (this._end) {
90
- const offset = pageOffset(this._end.target);
91
- this.end.y = offset.top + offset.height * this._end.offset;
92
- } else {
93
- this.end.y = this.start.y + pageOffset(this._start.target).height;
124
+ // todo we need to calculate the position for each timeline
125
+ //
126
+ // calculate the positions and offsets
127
+ // if we are missing one extend them
128
+
129
+ let previousY = -1;
130
+
131
+ this.offsets = this._triggers.map(t => {
132
+ const offset = pageOffset(t.target);
133
+
134
+ const y = offset.top + offset.height * t.offset;
135
+
136
+ if (y < previousY) throw new Error('offsets are not in order');
137
+
138
+ let position;
139
+ if (typeof t.position === 'string') {
140
+ if (this.timelines.length !== 1)
141
+ throw new Error(
142
+ 'labels can only be used with one timeline',
143
+ );
144
+
145
+ position = this.timelines[0].labelPosition(t.position);
146
+ } else if (t.position >= 0 || t.position <= 1) {
147
+ position = t.position;
148
+ } else {
149
+ throw new Error('position should be between 0 and 1');
150
+ }
151
+
152
+ return {
153
+ y,
154
+ view: t.view,
155
+ position,
156
+ };
157
+ });
158
+
159
+ if (this.offsets.length < 1)
160
+ throw new Error('scroll timeline needs at least one trigger');
161
+
162
+ if (this.offsets.length === 1) {
163
+ this.offsets.push({
164
+ y:
165
+ this.offsets[0].y +
166
+ pageOffset(this._triggers[0].target).height,
167
+ view: 1,
168
+ position: 1,
169
+ });
94
170
  }
95
171
  }
96
172
 
97
- _onScroll({ y, height }: { y: number; height: number }) {
173
+ private _onScroll({ y, height }: { y: number; height: number }) {
98
174
  if (!this._initialized) {
99
175
  this.init();
100
176
  this._initialized = true;
101
177
  }
102
178
 
103
- const start = this.start.y + height * this.start.view;
104
- const end = this.end.y + height * this.end.view;
179
+ // find the matching offset
180
+ // rolling window
181
+ for (let i = 1; i < this.offsets.length; i++) {
182
+ const start = this.offsets[i - 1];
183
+ const end = this.offsets[i];
105
184
 
106
- const dif = end - start;
107
- const x = 1 - (end - y) / dif;
185
+ const startY = start.y + height * start.view;
186
+ const endY = end.y + height * end.view;
108
187
 
109
- for (const timeline of this.timelines) {
110
- timeline.seek(x);
111
- }
112
- }
113
- }
188
+ const dif = endY - startY;
189
+ const x = 1 - (endY - y) / dif;
114
190
 
115
- function parseStart(val: any): StartEndOffset {
116
- // might be an object { target, offset }
117
- if (!val) {
118
- throw new Error(
119
- 'unknown start property use an html element or an object',
120
- );
121
- }
122
-
123
- let element = null;
124
- let offset = 'top';
191
+ for (const timeline of this.timelines) {
192
+ // calc pos range
193
+ const pos =
194
+ start.position + (end.position - start.position) * x;
125
195
 
126
- if (typeof val === 'object') {
127
- if (val instanceof HTMLElement) element = val;
128
- else if ('target' in val) {
129
- element = val.target;
130
- if (typeof val.offset !== 'undefined') offset = val.offset;
131
- } else {
132
- throw new Error('start unknown ' + val);
196
+ timeline.seek(pos);
197
+ }
133
198
  }
134
- } else {
135
- throw new Error('unknown start val');
136
199
  }
137
-
138
- return {
139
- target: element,
140
- offset: parseOffset(offset),
141
- };
142
200
  }
143
201
 
144
- function parseEnd(val: any): StartEndOffset | null {
202
+ /**
203
+ * Parse the start property
204
+ *
205
+ * can be an HTMLElement or an object { target, offset }
206
+ *
207
+ * the default offset is top
208
+ * the default view is top
209
+ */
210
+ function parseTrigger(
211
+ val: ScrollTrigger,
212
+ position: Position | undefined,
213
+ i: number,
214
+ ): ParsedScrollTrigger {
145
215
  // might be an object { target, offset }
146
- if (!val) return null;
216
+ if (!val) {
217
+ throw new Error('unknown property use an html element or an object');
218
+ }
147
219
 
148
220
  let element = null;
149
- let offset = 'top';
221
+ let offset: OffsetValue = 'top';
222
+ let view: OffsetValue = i == 0 ? 'top' : 'bottom';
150
223
 
151
224
  if (typeof val === 'object') {
152
- if (val instanceof HTMLElement) element = val;
153
- else if ('target' in val) {
225
+ if (val instanceof HTMLElement) {
226
+ element = val;
227
+ } else if ('target' in val) {
154
228
  element = val.target;
155
229
  if (typeof val.offset !== 'undefined') offset = val.offset;
230
+ if (typeof val.view !== 'undefined') view = val.view;
156
231
  } else {
157
232
  throw new Error('start unknown ' + val);
158
233
  }
@@ -163,21 +238,30 @@ function parseEnd(val: any): StartEndOffset | null {
163
238
  return {
164
239
  target: element,
165
240
  offset: parseOffset(offset),
241
+ view: parseOffset(view),
242
+ position: position ?? (i == 0 ? 0 : 1),
166
243
  };
167
244
  }
168
245
 
169
- function parseOffset(val: any): number {
246
+ /**
247
+ * Parse the offset value
248
+ *
249
+ * can be a string (top, center, bottom) or a number (0-1)
250
+ *
251
+ * 0 = top
252
+ * 0.5 = center
253
+ * 1 = bottom
254
+ */
255
+ function parseOffset(val: OffsetValue): number {
170
256
  if (typeof val === 'string') {
171
257
  if (val === 'top') return 0;
172
-
173
258
  if (val === 'center') return 0.5;
174
-
175
259
  if (val === 'bottom') return 1;
176
260
 
177
261
  throw new Error('unknown view value ' + val);
178
262
  }
179
263
 
180
- if (typeof val !== 'number') {
264
+ if (typeof val !== 'number' || val < 0 || val > 1) {
181
265
  throw new Error(
182
266
  'view expecting to be a top/center/bottom or a percent value',
183
267
  );
@@ -0,0 +1,8 @@
1
+ import Scroll from './public.js';
2
+
3
+ /**
4
+ * Create a scroll animation
5
+ */
6
+ export function scroll(): Scroll {
7
+ return new Scroll();
8
+ }
@@ -1,20 +1,31 @@
1
- import PublicTimeline from '../timeline/public';
2
- import Scroll from './Scroll';
1
+ import { Timeline } from '../chnobli.js';
2
+ // import Scroll from './Scroll.js';
3
+ import ScrollTimeline, { Position, ScrollTrigger } from './Scroll.js';
3
4
 
4
- export default class PublicScroll {
5
- private _inner: Scroll;
5
+ export default class Scroll {
6
+ private _inner: ScrollTimeline;
6
7
 
7
- /*
8
- {
9
- start: el | px
10
- startView: 'top'
8
+ constructor() {
9
+ this._inner = new ScrollTimeline();
11
10
  }
12
- */
13
- constructor(props: Record<string, any> = {}) {
14
- this._inner = new Scroll(props);
11
+
12
+ /**
13
+ * Add a trigger to the timeline
14
+ *
15
+ * Providing an offset at which point the trigger should end
16
+ */
17
+ add(trigger: ScrollTrigger, position?: Position): this {
18
+ this._inner.add(trigger, position);
19
+
20
+ return this;
15
21
  }
16
22
 
17
- add(timeline: PublicTimeline) {
23
+ /**
24
+ * Add a timeline to the scroll
25
+ */
26
+ addTimeline(timeline: Timeline): this {
18
27
  this._inner.addTimeline(timeline);
28
+
29
+ return this;
19
30
  }
20
31
  }
@@ -3,31 +3,48 @@
3
3
  * allowing to easely offset each target by a few pixels
4
4
  */
5
5
 
6
- function isStagger(value: any) {
6
+ function isStagger<O>(value: any): value is Stagger<O> {
7
+ const v = value as any;
8
+
7
9
  return (
8
- typeof value === 'object' &&
9
- value !== null &&
10
- typeof value.__isStagger__ === 'function'
10
+ typeof v === 'object' &&
11
+ v !== null &&
12
+ typeof v.__isStagger__ === 'function'
11
13
  );
12
14
  }
13
15
 
14
- export function callStagger(value: any, i: number, l: any = null) {
15
- if (isStagger(value)) return value.call(i, l);
16
+ export function callStagger<O>(
17
+ value: O | Stagger<O>,
18
+ i: number,
19
+ length?: number,
20
+ ): O {
21
+ if (isStagger(value)) return value.call(i, length);
16
22
 
17
23
  return value;
18
24
  }
19
25
 
20
- export function staggerMap(value: any, fn: (v: any) => any) {
21
- if (isStagger(value))
22
- return new Stagger((...args: any[]) => fn(value.call(...args)));
26
+ export function staggerMap<O, NO>(
27
+ value: O | Stagger<O>,
28
+ fn: (val: O) => NO,
29
+ ): NO | Stagger<NO> {
30
+ if (isStagger(value)) {
31
+ return new Stagger((i: number, length?: number) =>
32
+ fn(value.call(i, length)),
33
+ );
34
+ }
23
35
 
24
36
  return fn(value);
25
37
  }
26
38
 
27
- export default class Stagger {
28
- private fn: (...args: any[]) => any;
39
+ export type StaggerValue<O> = (i: number, length?: number) => O;
40
+
41
+ export default class Stagger<O> {
42
+ private fn: StaggerValue<O>;
29
43
 
30
- constructor(value: any) {
44
+ /**
45
+ * @ignore
46
+ */
47
+ constructor(value: StaggerValue<O>) {
31
48
  if (typeof value === 'function') {
32
49
  this.fn = value;
33
50
  return;
@@ -37,9 +54,12 @@ export default class Stagger {
37
54
  throw new Error('unknown stagger value ' + value);
38
55
  }
39
56
 
40
- call(...args: any[]) {
41
- return this.fn(...args);
57
+ call(i: number, length?: number): O {
58
+ return this.fn(i, length);
42
59
  }
43
60
 
61
+ /**
62
+ * @ignore
63
+ */
44
64
  __isStagger__() {}
45
65
  }
@@ -1,5 +1,5 @@
1
- import Value from '../values/Value';
2
- import StyleValue from '../values/StyleValue';
1
+ import Value from '../values/Value.js';
2
+ import StyleValue from '../values/StyleValue.js';
3
3
 
4
4
  export default class BaseTarget<T> {
5
5
  target: T;
@@ -1,6 +1,6 @@
1
- import Value from '../values/Value';
2
- import StyleValue from '../values/StyleValue';
3
- import { Target } from './Target';
1
+ import Value from '../values/Value.js';
2
+ import StyleValue from '../values/StyleValue.js';
3
+ import { Target } from './Target.js';
4
4
 
5
5
  export type Element = HTMLElement | SVGElement;
6
6
 
@@ -0,0 +1,124 @@
1
+ import StyleValue from '../values/StyleValue.js';
2
+ import Value from '../values/Value.js';
3
+ import { Target } from './Target.js';
4
+
5
+ export default class ObjectTarget implements Target {
6
+ private target: Record<string, any>;
7
+
8
+ // private _extFns: ExternalFunctions;
9
+
10
+ // private transformValues: Map<string, (Value | null)[]>;
11
+ private styleValues: Map<string, StyleValue | undefined>;
12
+ // private values: Map<string, Value>;
13
+
14
+ /**
15
+ * target a dom node or svg
16
+ *
17
+ * extFns: {getComputedStyle, getRootElement}
18
+ */
19
+ constructor(target: Record<string, any>) {
20
+ this.target = target;
21
+
22
+ this.styleValues = new Map();
23
+ // this.values = new Map();
24
+ }
25
+
26
+ inner() {
27
+ return this.target;
28
+ }
29
+
30
+ type() {
31
+ return 'object';
32
+ }
33
+
34
+ getValue(name: string): Value | null {
35
+ // return this.values.get(name) ?? null;
36
+ throw new Error('not supported');
37
+ }
38
+
39
+ setValue(name: string, value: Value) {
40
+ // this.values.set(name, value);
41
+ throw new Error('not supported');
42
+ }
43
+
44
+ removeValue(name: string) {
45
+ // this.values.delete(name);
46
+ throw new Error('not supported');
47
+ }
48
+
49
+ getTransformValue(name: string): Value | null {
50
+ throw new Error('not supported');
51
+ }
52
+
53
+ setTransformValue(name: string, value: Value) {
54
+ throw new Error('not supported');
55
+ }
56
+
57
+ removeTransformValue(name: string) {
58
+ throw new Error('not supported');
59
+ }
60
+
61
+ getStyleValue(name: string): StyleValue | null {
62
+ const v = this.styleValues.get(name) ?? null;
63
+
64
+ if (v !== null) return v;
65
+
66
+ const styleV = this.target[name];
67
+ if (typeof styleV === 'undefined' || styleV === null) {
68
+ return styleV;
69
+ }
70
+
71
+ try {
72
+ const value = StyleValue.parse(styleV);
73
+ this.styleValues.set(name, value);
74
+
75
+ return value;
76
+ } catch (e) {
77
+ console.log('could not parse value', styleV);
78
+ return v;
79
+ }
80
+ }
81
+
82
+ setStyleValue(name: string, value: StyleValue): void {
83
+ this.styleValues.set(name, value);
84
+ }
85
+
86
+ removeStyleValue(name: string): void {
87
+ this.styleValues.set(name, undefined);
88
+ }
89
+
90
+ hasClass(name: string): boolean {
91
+ throw new Error('not supported');
92
+ }
93
+
94
+ addClass(name: string): void {
95
+ throw new Error('not supported');
96
+ }
97
+
98
+ removeClass(name: string): void {
99
+ throw new Error('not supported');
100
+ }
101
+
102
+ unifyValues(name: string, a: Value, b: Value): [Value, Value] {
103
+ if (a.unit === b.unit) return [a, b];
104
+
105
+ if (!a.unit && b.unit) a.unit = b.unit;
106
+
107
+ if (!b.unit && a.unit) b.unit = a.unit;
108
+
109
+ return [a, b];
110
+ }
111
+
112
+ apply() {
113
+ // style
114
+ for (const [k, v] of this.styleValues.entries()) {
115
+ if (v === undefined) {
116
+ console.log('delete', k);
117
+ delete this.target[k];
118
+ this.styleValues.delete(k);
119
+ } else {
120
+ this.target[k] = v.toMixed();
121
+ }
122
+ }
123
+ }
124
+ }
@@ -1,6 +1,15 @@
1
- import Value from '../values/Value';
2
- import DomTarget from './DomTarget';
3
- import StyleValue from '../values/StyleValue';
1
+ import Value from '../values/Value.js';
2
+ import DomTarget from './DomTarget.js';
3
+ import StyleValue from '../values/StyleValue.js';
4
+ import type TestDomNode from './TestDomNode.js';
5
+ import ObjectTarget from './ObjectTarget.js';
6
+
7
+ export type Targets = AnimationTarget | AnimationTarget[];
8
+ export type AnimationTarget =
9
+ | HTMLElement
10
+ | SVGElement
11
+ | TestDomNode
12
+ | Record<string, any>;
4
13
 
5
14
  export function newTarget(target: any): Target {
6
15
  if (typeof window === 'undefined') {
@@ -19,6 +28,10 @@ export function newTarget(target: any): Target {
19
28
  }
20
29
  }
21
30
 
31
+ if (typeof target === 'object' && target !== null) {
32
+ return new ObjectTarget(target);
33
+ }
34
+
22
35
  throw new Error('unknown target');
23
36
  }
24
37