You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This will animate the above element by way of its style properties, as specified in the keyframes. This is only the default behaviour; you can get far more funky with it.
51
+
52
+
The above is plucked directly from the [`demo/simple`](demo/simple/App.vue) Vue file.
53
+
54
+
## Table of Contents
55
+
56
+
-[keyframes.js ](#keyframesjs-)
57
+
-[Quick Start using `CSS`](#quick-start-using-css)
58
+
-[Create a new `CSSKeyframesAnimation` object:](#create-a-new-csskeyframesanimation-object)
59
+
-[Specify your keyframes in CSS:](#specify-your-keyframes-in-css)
60
+
-[Add the keyframes to your animation, and add target elements to animate:](#add-the-keyframes-to-your-animation-and-add-target-elements-to-animate)
-[Unit interpolation and resolution](#unit-interpolation-and-resolution)
80
+
81
+
## Installation
82
+
83
+
```bash
84
+
npm install keyframes.ts
37
85
```
38
86
39
-
## `Animation` and `CSSKeyFramesAnimation`
87
+
Which will _mostly_ work both in and out of the browser. Anything that leverages the the `DOM`, of course, won't work outside of the browser (things like `getComputedStyle`, `document`, etc.).
40
88
41
-
## Groups of `Animation`
89
+
## `Animation`
42
90
43
-
## Math
91
+
The `Animation` object is the driver behind `CSSKeyFramesAnimation` and `AnimationGroup`.
44
92
45
-
The more interesting part of the library is the collection of various timing functions housed within
46
-
[`easing.ts`](src/easing.ts), with utility math functions being defined in [`math.ts`](src/math.ts).
93
+
Every `Animation` is composed of (at a high level):
47
94
48
-
### Bezier Curves
95
+
- options: the options for the animation; `AnimationOptions`
96
+
- a transform function: the function to interpolate between keyframes
97
+
- a timing function: the function to ease the animation, which can also be set by the `AnimationOptions`
98
+
- keyframes: the keyframes for the animation; `TemplateAnimationFrame`
49
99
50
-
For instance, `deCasteljau` is a dynamic programming implementation thereof, allowing for (semi) fast n-th degree Bezier curve calculations. This is used by every `bezier*` function herein.
100
+
### [`AnimationOptions`](src/animation.ts#L139):
51
101
52
-
To create your own n-th degree Bezier timing function, you can use the aforesaid; to create the more common cubic Bezier curve, the appellative `cubicBezier` is provided: it's essentially identical in function to the similar CSS variant thereof:
102
+
- duration: time in milliseconds of the entire animation
103
+
- delay: time in milliseconds before the animation starts
104
+
- iterationCount: number of times the animation should repeat
105
+
- direction: direction of the animation (normal, reverse, alternate, alternate-reverse)
106
+
- fillMode: how the animation should apply styles before and after it plays (none, forwards, backwards, both)
107
+
- timing function: the timing function to use for easing, tweening, etc., the animation
108
+
-
109
+
110
+
### The transform function
111
+
112
+
The type signature of the transform function is as follows:
And it's called for each timestep `t` of the animation, where `t` is a number between 0 and the duration of the animation. The transform function is responsible for doing whatever you'd like to do with the variables `v` at each timestep `t`.
119
+
120
+
The variables `v` are the interpolated values at time `t`, given to you in almost exactly the same form as you originally specified them in the keyframes. Deeply nested objects are supported, as are just about anything else you can think of.
121
+
122
+
Every value therein is parsed as a CSS value unit, so you can specify things like `1px`, `1em`, `1%`, `1deg`, etc. The library will handle the conversion for you, though two interpolate between two different units, they must be of the same super type (e.g. `px` and `em` are both `length`s, so they can be interpolated; `px` and `deg` are not, so they cannot). See the `collapseNumericType` function within [`units.ts`](src/units.ts) for more information.
123
+
124
+
### The timing function
125
+
126
+
The timing, or easing, tweening, etc., function is responsible for determining how the animation progresses over time. The type signature of the timing function is as follows:
127
+
128
+
```ts
129
+
typeTimingFunction= (t:number) =>number;
130
+
```
131
+
132
+
Where `t` is a number between 0 and 1, and the return value is also a number between 0 and 1. The timing function is responsible for determining how the animation progresses over time, and can be anything from a simple linear function to a complex Bezier curve.
133
+
134
+
All CSS timing functions are supported, and are implemented in [`easing.ts`](src/easing.ts).
135
+
136
+
#### Step Functions
137
+
138
+
A special case and multi-parameter variant of a timing function, implemented as `steppedEase`, which takes (in addition to `t`) two parameters:
139
+
140
+
- the number of steps
141
+
- the direction, or jump term, of the step
142
+
143
+
Valid jump terms are:
144
+
145
+
-`jump-none`: the step occurs at the start of the step, but the value is held until the end of the step
146
+
-`jump-start` | `start`: the step occurs at the start of the step
147
+
-`jump-end` | `end`: the step occurs at the end of the step
148
+
-`jump-both` | `both`: the step occurs at the start and end of the step
149
+
150
+
#### Bézier Curves
151
+
152
+
Bézier curves are parametric curves defined by a set of control points.
153
+
154
+
The `cubicBezier` function implements the special cubic case of the more general Bézier curve, taking in control points for `x1`, `y1`, `x2`, and `y2`, and returning the x and y coordinates of the curve at time `t`.
> _`cubicBezier` returns both the x and y coordinates: typically one's only interested in the y._
160
+
The general case of calculating a point along a Bézier curve at time `t`, specified at control points `x1, ..., xn`, `y1, ..., yn`, is performed using `deCasteljau`'s algorithm, implemented iteratively as simply the `deCasteljau` function.
161
+
162
+
Both of the above, along with other math utilities, are implemented in [`math.ts`](src/math.ts).
163
+
164
+
#### Graphing Bézier Curves
165
+
166
+
If you're interested in more Bézier visualizations, check out [this](https://www.desmos.com/calculator/tvivnkflzv) Desmos graph.
167
+
168
+
Or use any of the demos in the [`demo`](demo) folder, click on `timing-functions` and then `bezier`.
169
+
170
+
#### Just gimme the `t` value
171
+
172
+
OK ✨
173
+
174
+
`CSSBezier` is the function you're looking for. It's a high-order function that takes in the control points of the Bezier curve and returns a function that takes in a time `t` and returns the value of the Bezier curve at that time.
175
+
176
+
For example, CSS's `easeInBounce` is defined as
177
+
178
+
```ts
179
+
function easeInBounce(t:number) {
180
+
t=CSSBezier(0.09, 0.91, 0.5, 1.5)(t);
181
+
returnt;
182
+
}
183
+
```
184
+
185
+
### `TemplateAnimationFrame`
186
+
187
+
A `TemplateAnimationFrame` object, or template keyframe, is a keyframe that's not yet been resolved to a concrete keyframe. It's composed of:
188
+
189
+
- id: the unique id of the keyframe; autoincremented number
190
+
- start: the start time of the keyframe
191
+
- vars: the variables of the keyframe to be interpolated
192
+
- transform: the transform function of the keyframe
193
+
- timingFunction: the timing function of the keyframe
194
+
195
+
Keyframes can have unique transform and timing functions, but that's not typical: usually you'll specify one transform and timing function for the entire animation (once a transform function is specified, it's used for all keyframes, similarly for the timing function; no need to list it twice).
196
+
197
+
#### Reification of a `TemplateAnimationFrame`
198
+
199
+
A `TemplateAnimationFrame` is reified into a concrete keyframe by the following process:
200
+
201
+
- parse the start time: this can be input as a string, which can take on any valid CSS time format (e.g. `1s`, `100ms`, `1.5s`, `1.5ms`, etc.), or as a number, or as a percentage (e.g. `50%`).
202
+
- All times are then normalized to a percentage of the total duration of the animation.
203
+
- resolve the transform and timing functions if they're null: if they are, they're resolved to the default transform and timing functions specified in the `AnimationOptions`.
204
+
205
+
Once all of the `TemplateAnimationFrame` objects have been added to an `Animation`, they're further parsed into a concrete keyframe by the following process:
206
+
207
+
- sort the keyframes by their starting percentage
208
+
- resolve the variables for each keyframe
209
+
- resolve the keyframes' start and stop times
210
+
- calculate the keyframes' duration
211
+
212
+
##### Variable Resolution
213
+
214
+
This is done so that every keyframe has the same set of variables, and so that the variables are resolved to their concrete values. Take the following example:
215
+
216
+
```ts
217
+
const keyframeVars1 = {
218
+
x: 0,
219
+
y: 0,
220
+
};
221
+
const keyframeVars2 = {
222
+
z: 0,
223
+
};
224
+
const keyframeVars3 = {
225
+
x: 1,
226
+
y: 1,
227
+
z: 1,
228
+
};
229
+
```
230
+
231
+
Notice that `x` and `y` are defined in the first and third keyframes, but not in the second. We handle this by working through the keyframes backwards and seeking the most recent keyframe that has the variable defined.
232
+
233
+
If it's not defined in any previous keyframes, we set it to the default value of the variable (usually `0`).
234
+
235
+
All of this above nets you the ability to specify keyframes in a rather hap-hazard way (perhaps not such a good thing 😅). For example, the below is a valid set of keyframes:
236
+
237
+
```ts
238
+
const duration =1000;
239
+
const keyframe1 = {
240
+
start: "0s",
241
+
vars: {
242
+
x: 0,
243
+
y: 0,
244
+
},
245
+
};
246
+
247
+
const keyframe2 = {
248
+
start: "100%",
249
+
vars: {
250
+
x: 0,
251
+
y: 1,
252
+
},
253
+
};
254
+
255
+
const keyframe3 = {
256
+
start: "500ms",
257
+
vars: {
258
+
x: 1,
259
+
},
260
+
};
261
+
```
262
+
263
+
## `CSSKeyframesAnimation`
264
+
265
+
An abstraction over the `Animation` object, the `CSSKeyframesAnimation` object is responsible for creating animations from CSS keyframes. This is done by parsing the CSS keyframes into a series of `TemplateAnimationFrame` objects, thereupon adding them to a base `Animation` object.
target?: HTMLElement,)`: interpolates between two units
59
315
60
-
I strongly recommend you use [this](https://cubic-bezier.com/) great website to play around within different curves visually.
316
+
Note that any `ValueUnit` type variant can be interpolated between another; insofar as, a `ValeUnit` can be interpolated between a `FunctionValue` or `ValueArray`, and vice versa. The values thereof are aligned to the smallest array length of the two: the interpolation is then performed on each element of the array.
61
317
62
-
Finally, as another interactive Bezier demo, you can check out [this](https://www.desmos.com/calculator/tvivnkflzv) Desmos graph I've made. Pretty neat!
318
+
#### Unit interpolation and resolution
63
319
64
-
### [`easing.ts`](src/easing.ts)
320
+
Units that are of the same supertype can be interpolated between. For example, `px` and `em` are both `length`s, so they can be interpolated between. `px` and `deg` are not, so they cannot.
65
321
66
-
Additionally, a portion of [Robert Penner's](http://robertpenner.com/easing/) set of easing functions are implemented, though using a modified scheme which assumes the input `t` value is on the unit interval `[0, 1]`
322
+
Supertypes also contain information about the realtive or absolute nature of the unit. For example, `px` is an absolute length, while `em` is a relative length. This information is used to resolve the units to a common supertype, which is then used to interpolate between the two units.
0 commit comments