1 | [![img](http://i.imgur.com/2YkqCOS.png)](http://mattdesl.github.io/keytime/demo/dom/)
|
2 | <sup>[click to view demo](http://mattdesl.github.io/keytime/demo/dom/)</sup>
|
3 |
|
4 | # keytime
|
5 |
|
6 | [![experimental](http://badges.github.io/stability-badges/dist/experimental.svg)](http://github.com/badges/stability-badges)
|
7 |
|
8 | Modular keyframe-based animation tools. Currently at a work-in-progress/proof-of-concept stage.
|
9 |
|
10 | The idea is to break down animation data into a simple format that can easily be manipulated and used in real-time playback. Some novel goals of the project:
|
11 |
|
12 | - modular; the tools can be used independently of render engine, and may be useful to non-JavaScript devs (for e.g. Java/C++/C# game devs)
|
13 | - concise and standard animation format that is application agnostic
|
14 | - no assumptions about what is being animated; could be numbers, 2D paths, vectors, quaternions, etc
|
15 | - custom interpolators and easing functions are easy to add (e.g. interpolating CSS properties)
|
16 | - easy to pipe into other tools, like a visual editor for designers
|
17 | - using CommonJS and JSON to export animation data, so you can `require('mattdesl/my-fancy-timeline')` and build an ecosystem of timelines and animations
|
18 |
|
19 | This does not implement its own loop or `play()`, `pause()` methods. It simply allows the developer to retrieve interpolated values at an arbitrary time stamp (which may be in seconds, milliseconds, centuries, or whatever).
|
20 |
|
21 | ## example
|
22 |
|
23 | An example of how it might look within a render loop:
|
24 |
|
25 | ```js
|
26 | var rgba = require('color-style')
|
27 | var data = require('./anim-data.js')
|
28 |
|
29 | var timeline = require('keytime')(data)
|
30 |
|
31 | //our basic sprite object
|
32 | var sprite = {
|
33 | fillStyle: [255,255,255],
|
34 | alpha: 1,
|
35 | position: [0, 0]
|
36 | }
|
37 |
|
38 | //draw the frame at the given frame time
|
39 | function render(ctx, time) {
|
40 | //update the object with the animated properties
|
41 | timeline.values(time, sprite)
|
42 |
|
43 | //draw the sprite
|
44 | ctx.fillStyle = rgba(sprite.fillStyle)
|
45 | ctx.globalAlpha = sprite.alpha
|
46 | ctx.fillRect(sprite.position[0], sprite.position[1], 50, 50)
|
47 | }
|
48 | ```
|
49 |
|
50 | ## demos
|
51 |
|
52 | There are a couple examples in the [demo](demo/) folder. Some of them use the work in progress [keytime-editor](https://github.com/mattdesl/keytime-editor/).
|
53 |
|
54 | - [canvas/path animation](http://mattdesl.github.io/timeline-tests/demo1/index.html) - animates paths created with [path-illustrator](http://mattdesl.github.io/path-illustrator/demo/advanced.html)
|
55 | - [CSS animations and editor](http://mattdesl.github.io/keytime/demo/dom/index.html)
|
56 | - [CSS 3D transforms](http://mattdesl.github.io/keytime/demo/dom/index2.html)
|
57 | - [button proof of concept](http://mattdesl.github.io/keytime/demo/dom/index3.html)
|
58 |
|
59 |
|
60 | ## wiki
|
61 |
|
62 | - [keytime format](https://github.com/mattdesl/keytime/wiki/Format)
|
63 | - [subclassing keytime](https://github.com/mattdesl/keytime/wiki/Subclassing)
|
64 |
|
65 | ## usage
|
66 |
|
67 | [![NPM](https://nodei.co/npm/keytime.png)](https://nodei.co/npm/keytime/)
|
68 |
|
69 | This module builds on [keyframes](https://github.com/mattdesl/keyframes) to interpolate between keyframe values. The core concepts are as follows:
|
70 |
|
71 | #### `timeline`
|
72 |
|
73 | A `keytime` instance (or timeline) provides a list of named `properties` that make up this keyframed timeline. It also handles easing and interpolation. The default timeline interpolates numbers and arrays of numbers; and supports a [set of common easing equations](https://github.com/mattdesl/eases).
|
74 |
|
75 | ```js
|
76 | var timeline = require('keytime')(data)
|
77 |
|
78 | //get all values at a time stamp
|
79 | var values = timeline.values(3)
|
80 |
|
81 | //the value of 'position' property at this time stamp
|
82 | console.log( values.position )
|
83 | ```
|
84 |
|
85 | #### `properties`
|
86 |
|
87 | A property holds a set of [keyframes](https://github.com/mattdesl/keyframes), a unique `name` identifier and a default `value` (used when no keyframes are present).
|
88 |
|
89 | #### `keyframes`
|
90 |
|
91 | The keyframes hold a `time` stamp (no assumptions are made about unit of time), a `value` (can be array, number, object, etc). They can optionally include an `ease`. For a pair of keyframes, the second determines the easing function; so the ease of the first keyframe in a timeline is ignored.
|
92 |
|
93 | ## API
|
94 |
|
95 | #### `var timeline = require('keytime')([data])`
|
96 |
|
97 | Creates a new timeline with the optional data in the form of a JS object. The data is assumed to follow the [keytime format](https://github.com/mattdesl/keytime/wiki/Format).
|
98 |
|
99 | #### `timeline.values(timeStamp[, out])`
|
100 |
|
101 | A convenience method to grab all properties at the given time stamp. This returns an object with the property names and their associated value for that time. You can pass an `out` object to avoid creating a new one. So you can do this:
|
102 |
|
103 | ```js
|
104 | var sprite = { alpha: 1, x: 0, y: 0, width: 0, height: 0 }
|
105 |
|
106 | ... in render loop ...
|
107 | //store new values in sprite
|
108 | timeline.values(time, sprite)
|
109 |
|
110 | //draw the sprite
|
111 | ctx.globalAlpha = sprite.alpha
|
112 | ctx.fillRect(sprite.x, sprite.y, sprite.width, sprite.height)
|
113 | ```
|
114 |
|
115 | #### `timeline.property(name)`
|
116 |
|
117 | Searches the timeline and returns the first property by the given name, or index if a number was provided instead. If none is found, `undefined` is returned.
|
118 |
|
119 | #### `timeline.duration()`
|
120 |
|
121 | Determines the maximum time stamp for all keyframes in all of this timeline's properties.
|
122 |
|
123 | #### `timeline.valueOf(timeStamp, property)`
|
124 |
|
125 | For a given property, gets the interpolated value at that time stamp.
|
126 |
|
127 | #### `timeline.dispose()`
|
128 |
|
129 | Disposes all keyframes and all properties.
|
130 |
|
131 | #### `timeline.load(data)`
|
132 |
|
133 | Loads new animation data to this timeline.
|
134 |
|
135 | **NOTE:** This disposes and overrides the current set of properties/keyframes.
|
136 |
|
137 | #### `timeline.properties`
|
138 |
|
139 | An array containing all of the properties in this timeline. Each property has:
|
140 |
|
141 | - `name` the unique name
|
142 | - `value` a value to use as a constant (or default) when no keyframes exist
|
143 | - `keyframes` an instance of [keyframes](https://github.com/mattdesl/keyframes)
|
144 |
|
145 | And has the methods:
|
146 |
|
147 | - `property.dispose()` which clears its keyframes
|
148 | - `property.load(data)` which disposes the keyframes, then loads new property data
|
149 |
|
150 | ## running/building demos
|
151 |
|
152 | To run or build the demos, first install the necessary tools:
|
153 |
|
154 | ```npm install browserify beefy uglify-js -g```
|
155 |
|
156 | Then, pick your poison:
|
157 |
|
158 | ```sh
|
159 | # to run DOM demo
|
160 | npm run dev-dom
|
161 |
|
162 | # to run canvas demo
|
163 | npm run dev-canvas
|
164 |
|
165 | # to build DOM demo
|
166 | npm run build-dom
|
167 | ```
|
168 |
|
169 | ## License
|
170 |
|
171 | MIT, see [LICENSE.md](http://github.com/mattdesl/keytime/blob/master/LICENSE.md) for details.
|