Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rewrite using Class, add registerEasing method #1

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
examples/
229 changes: 151 additions & 78 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,121 +1,194 @@
# Storyline.js - Multi-purpose sequencer
# Storyline.js - JavaScript Animation Sequencer

**Storyline.js** is a library to help define a storyboard using natural language.

This is the refined and polished version of the sytem created for [BEYOND](http://b-e-y-o-n-d.com/) and [cru·ci·form](http://www.clicktorelease.com/code/cruciform/).
[Check all the demos](http://jordandelcros.github.io/Storyline.js/)

Check out the example to see it in action: [Storyline.js with CSS 2D transforms](http://www.clicktorelease.com/tools/storylinejs/).
### How to?

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/mQVU3Lb0D-w/0.jpg)](http://www.youtube.com/watch?v=mQVU3Lb0D-w)
The Storyline class only come with two options :
- storyboard: a simple object containing all keyframes.
- timescale: (optional) multiply all key's time with it.

#### Using Storyline.js ####

There's two parts: Storyline.js is the parser and player, and then a storyboard source object that defines the story. A storyline source has this format:
```javascript
var storyline = new Storyline(storyboard [, timescale]);
```

```json
{
"value1": [
"0 cut to 10",
"2 linear to 3"
],

"value2": [
"0 cut to 0",
"4 ease to 1",
"6 ease to 0"
]
}
#### Storyboard hierarchy

- name: the name of the animation.
- time: the begining of the current value to the next one in milliseconds.
- easing: the easing to use.
- value: the value(s) to animate (multiple values are between parenthesis).

```javascript
{
{name}: [
"{time} {easing} to {value}",
"{time} {easing} to {value}",
"{time} {easing} to {value}"
],
{name}: [
"{time} {easing} to ({value}, {value}, {value})",
"{time} {easing} to ({value}, {value}, {value})"
]
}
```

This source object is a map of keys (each key is a value that you will be using in your code *x*, *angle*, *power*, etc.), and each key contains an array of entries. Each entry defines a point in time, and a storyline action, and has the following syntax:
#### Timing

Each key times are in milliseconds.

```javascript
var storyline = new Storyline({
key1: [
"0 cut to 0",
"500 linear to 1",
"1000 linear to 2"
]
});
```
{time in seconds} {action to perform} {value of action}

You may need to create animations with a limited duration, you can use the `timescale` option to do that.
Each time will be multiplied by the `timescale`.

```javascript

var duration = 5000; // timescale of 5s

var storyline = new Storyline({
key1: [
"0 cut to 0",
"0.3 linear to 3",
"1 linear to 4"
]
}, duration);
```

The actions are:
#### Easing

There is already some basic easings:
- cut: immediately switch to the value if the time is upper or equal to the key.
- linear: linearly interpolate to the value.
- easeIn: ease in from the previous value to the key value.
- easeOut: ease out from the previous value to the key value.
- easeInOut: ease in and out from the previous value to the key value.
- easeInElastic: ease in elastic from the previous value to the key value.
- easeOutElastic: ease out elastic from the previous value to the key value.
- easeInOutElastic: ease in and out elastic from the previous value to the key value.
- easeInBounce: ease in bounce from the previous value to the key value.
- easeOutBounce: ease out bounce from the previous value to the key value.
- easeInOutBounce: ease in and out bounce from the previous value to the key value.
- quadratic(from,c,to): get value along a qaudratic bezier curve (see [stackoverflow explainations](http://stackoverflow.com/questions/5634460/quadratic-bezier-curve-calculate-point)).
- cubic(from,cx,cy,to): get value along a cubic bezier curve (see [stackoverflow explainations](http://stackoverflow.com/questions/5634460/quadratic-bezier-curve-calculate-point)).

- *cut to* instanteously changes to {value}
- *linear to* will linearly interpolate from the last defined value to {value}
- *ease to* will ease in-out from the last defined value to {value}
But you can also register your own easings:

#### Minimal example ####
```javascript
Storyline.registerEasing(customEasingName, function( elapsed, duration, options ){

Include Storyline.js
return (elapsed / duration); // Linear easing

```html
<script src="Storyline.js"></script>
});
```

Create a storyline from a structured storyboard source. By calling storyline.get you can get the updated value:
- elpsed: normalized elpased time (between 0 and 1).
- duration: normalized duration (always 1...)
- options: array of values, only if the easing take options (parenthesis with parameters).

```js
var storyline = STORYLINE.parseStoryline( {
#### Type

"value1": [
"0 cut to 0",
"5 ease to 1",
"10 ease to 0"
]

} );
You can animate one or many values in each keys but you can also use types:
- int: only returns integers.
- bool: return true if the value is upper or equal to 1, else return false.
- vec2: return the values with `.x` and `.y` getters.
- vec3: return the values with `.x`, `.y` and `.z` getters.
- color: return the values with `.r`, `.g`, `.b`, `hex` and `hexString` getters.

function update() {

requestAnimationFrame( update );
console.log( storyline.get( 'value1', ( Date.now() / 1000 ) % 10 ) );

}
But you can also register your own types:

update();
```
`Storyline.registerType(name, getter, setter)`

```javascript
Storyline.registerType("invert", function( options, originOptions ){

for( var option = 0, length = options.length; option < length; option++ ){

options[option] *= -1;

};

#### External storyboard example ####
return options;

Simply export the storyline into its own file, and include it like a normal script.
}, function( options, originString ){

```js
var storyline = STORYLINE.parseStoryline( {
return options;

"value1": [
});

```

### Examples

#### Simple

```javascript
var storyline = new Storyline({
key1: [
"0 cut to 0",
"5 ease to 1",
"10 ease to 0"
"500 easeIn to 360",
"1000 linear to 180"
],
key2: [
"500 cut to 180",
"1000 lienar to 0"
]

} );
```
});

Or load the content with AJAX and parse it when it's loaded:
function update( now ){

```js
var oReq = new XMLHttpRequest();
oReq.onload = function() {
storyline = STORYLINE.parseStoryline( this.responseText );
/* ready to use */
};
oReq.open( 'get', 'storyboard.json', true);
oReq.send();
```
window.requestAnimationFrame(update);

### Status ####
var key1 = storyline.get("key1", now);
var key2 = storyline.get("key2", now);

This is the first release. Next steps are to add syntax to control the easing functions, probably something like:
};

```
{time} ease to {value} { [ set of easing control points] }
window.requestAnimationFrame(update);
```

Also, support specific functions to simplify animations:
#### With fixed duration

```
{time} {wiggle|shake} {extent}
```javascript
var storyline = new Storyline({
key1: [
"0 cut to 0",
"0.5 easeIn to 360",
"1 linear to 180"
],
key2: [
"0.5 cut to 180",
"1 lienar to 0"
]
}, 1000);

function update( now ){

window.requestAnimationFrame(update);

var key1 = storyline.get("key1", now);
var key2 = storyline.get("key2", now);

};

window.requestAnimationFrame(update);
```

As always: forks, pull requests and code critiques are welcome!
[Check all the demos/examples](http://jordandelcros.github.io/Storyline.js/)

#### License ####
#### License

MIT licensed

Copyright (C) 2015 Jaume Sanchez Elias, http://www.clicktorelease.com
Original idea from [Jaume Sanchez Elias](http://www.clicktorelease.com)
Entirely rewrited by [Jordan Delcros](http://www.jordan-delcros.com)
Loading