diff --git a/docs/json/class/Util_Tempo.json b/docs/json/class/Util_Tempo.json index 9868b228..eefcf766 100644 --- a/docs/json/class/Util_Tempo.json +++ b/docs/json/class/Util_Tempo.json @@ -164,11 +164,11 @@ { "comment": "This is a core function that let you specify a rhythm and then define responses by calling the `start` and `progress` functions from the returned object. See [Animation guide](../guide/Animation-0700.html) for more details.\nThe `start` function lets you set a callback on every start. It takes a function ([`ITempoStartFn`](#link)).\nThe `progress` function lets you set a callback during progress. It takes a function ([`ITempoProgressFn`](#link)). Both functions let you optionally specify a time offset and a custom name.\nSee [Animation guide](../guide/animation-0700.html) for more details.", "returns": "ITempoResponses", - "returns_comment": "a object with chainable functions\n", + "returns_comment": "an object with chainable functions\n", "parameters": [ { "name": "beats", - "comment": "a rhythm in beats as a number or array of numbers", + "comment": "a rhythm in beats as a number or an array of numbers", "type": "number | number[]", "default": false } diff --git a/guide/Animation-0700.html b/guide/Animation-0700.html index 1630188c..e8c045a8 100644 --- a/guide/Animation-0700.html +++ b/guide/Animation-0700.html @@ -19,9 +19,9 @@ ≡
There are many great javascript animation libraries which you may use alongside Pts. For simple use cases, Pts' Tempo
utility class provides an intuitive and lightweight alternative.
Animation sequences are commonly implemented as a curated list of tweens played in milliseconds. But what if we take the idea one level higher, and think of it like a dance? Like One-two-three, One-two-three...
-Let's start by setting the beats. Tempo is usually measured in beats-per-minute (bpm), so there are two ways to initiate a Tempo
instance: by setting a bpm, or specifying the duration of a beat in milliseconds.
Tempo
is a lightweight utility class which helps you create animation sequences intuitively. It's an alternative to many other great animation libraries (which you can use with Pts too).
Typically, animation sequences are often implemented as a curated list of tweens in milliseconds. But what if we take the idea one level higher, and treat it like a dance? Like One-two-three, One-two-three...
+Let's start by counting the beats. Tempo is usually measured in beats-per-minute (bpm), so there are two ways to initiate a Tempo
instance: by setting a bpm, or specifying the duration of a beat in milliseconds.
// 120 beats-per-minute, or 500ms per beat
let tempo = new Tempo( 120 );
@@ -32,21 +32,22 @@
let everyTwo = tempo.every( 2 ); // count every 2 beats
let everyTen = tempo.every( 10 ); // count every 10 beats
-The every
function returns an object with two chainable functions: start(...)
and progress(...)
. The start
function lets you set a callback to be triggered at the start of every period. For example:
+The every
function returns an object with two chainable functions: start(...)
and progress(...)
. These functions let you attach custom callback functions that respond to animation events.
+The start
function lets you set a callback to be triggered at the start of every n-beats period. For example:
// at the start of every 2-beats period, do something
everyTwo.start( (count) => ... )
-The progress
function lets you specify a callback during the progress of every period, so you can use it to interpolate values and tween properties.
+The progress
function lets you set a callback during the progress of every n-beats period. The second parameter t
always start at 0 and ends at 1 in every period, so you can use it to interpolate values and tween properties.
// during every 10-beats period, do something
everyTen.progress( (count, t, time, isStart) => ... )
-Let's look at an example. Here the tempo is set to 60 BPM (or 1 second per beat), and we design the behaviors as such:
+Let's look at an example. Here the tempo is set to 60 BPM (or 1 second per beat), and we design the behaviors so that:
- Every 1 beat, the square's color changes
- Every 2 beats, the circle's color changes and the rotation completes once
-Pretty easy to create sychronized animation sequences, right? Let's try a few more example.
+Pretty easy to create synchronized animation sequences, right? Let's try a few more example.
Variations
Tween: Since the t
parameter in progress
callback function always go from 0 to 1, we can map its value to a Shaping
function and change the tweening style. Another neat trick is to use Num.cycle
to map the t
value from [0...1] to [0...1...0].
everyTwo.progress( (count, t, time, isStart) => {
@@ -65,13 +66,13 @@ Variations
Controls
-It's easy to control the speed of your animation by changing bpm by setting the Tempo.bpm
property. This makes it easier to synchronize your animations with music or in specific intervals.
+By changing bpm by setting the Tempo.bpm
property, you can control the speed of your animation. This makes it easier to synchronize your animations with music or at specific intervals.
tempo.bpm = 100; // set new bpm
tempo.bpm += 20; // make it 20 beats faster per minute
Try moving your cursor horizontally to change the bpm in this example:
-There are two ways to stop an animation. You can either add return true
in the callback functions, or include a name
in the third parameter of start
or progress
functions.
+There are two ways to stop an animation. You can either return true
within start
or progress
callback functions, or include a name
in the third parameter of the callbacks and then call tempo.stop( name )
.
let walking = (count, t) => {
// ...
return (count > 5); // return true will stop this animation
diff --git a/guide/Space-0500.html b/guide/Space-0500.html
index 2ca3ed6c..b11a620b 100644
--- a/guide/Space-0500.html
+++ b/guide/Space-0500.html
@@ -50,7 +50,7 @@ Players
}
} );
-Here we add an object that conforms to the IPlayer interface, which defines 4 optional callback functions:
+Here we add an object that conforms to the IPlayer interface, which defines 4 optional callback functions:
start
function is called when the space is ready. It includes 2 parameters: bound
which returns the bounding box, and space
which returns its space.
diff --git a/guide/js/examples/tempo_control.js b/guide/js/examples/tempo_control.js
index 385a0bc4..0fb9982e 100644
--- a/guide/js/examples/tempo_control.js
+++ b/guide/js/examples/tempo_control.js
@@ -7,6 +7,8 @@
let space = new CanvasSpace("#"+demoID).setup({ retina: true, bgcolor: "#e2e6ef", resize: true });
let form = space.getForm();
+ // -------
+
// Create tempo instance
let tempo = new Tempo(120);
@@ -16,31 +18,29 @@
return ( count, t ) => {
let tt = Shaping.quadraticInOut( t ); // shaping
lns[i] = Line.fromAngle( (i===0) ? space.center : lns[i-1].p2, Const.two_pi * tt, space.size.y/s );
- form.strokeOnly( c, 10, "round", "round").line( lns[i] );
+ form.strokeOnly( c, 10, "round", "round" ).line( lns[i] );
form.fillOnly( c ).point( lns[i].p2, 20, "circle" );
}
};
-
tempo.every( 6 ).progress( dials( 0, "#FFF", 4 ) )
tempo.every( 4 ).progress( dials( 1, "#123", 6 ) )
tempo.every( 2 ).progress( dials( 2, "#62E", 8 ) );
// track tempo animation
space.add( tempo );
+
space.add( (time, ftime) => {
let b = Num.clamp( (space.pointer.x - space.center.x)/5, -50, 50 );
tempo.bpm = 100 + Math.floor(b);
form.fillOnly("#123").text( [20, 32], `BPM is ${tempo.bpm}`);
});
-
- // start
+ // For use in demo page only
// Note that `playOnce(200)` will stop after 200ms. Use `play()` to run the animation loop continuously.
space.playOnce(200).bindMouse().bindTouch();
- // For use in demo page only
if (window.registerDemo) window.registerDemo(demoID, space);
})();
\ No newline at end of file
diff --git a/guide/js/examples/tempo_progress.js b/guide/js/examples/tempo_progress.js
index d5b8bc4b..a3fd672f 100644
--- a/guide/js/examples/tempo_progress.js
+++ b/guide/js/examples/tempo_progress.js
@@ -7,6 +7,8 @@
let space = new CanvasSpace("#"+demoID).setup({ retina: true, bgcolor: "#e2e6ef", resize: true });
let form = space.getForm();
+ // -------
+
// Create tempo instance
let tempo = new Tempo(60);
let colors = ["#62E", "#FFF", "#123"];
@@ -20,18 +22,17 @@
tempo.every( 2 ).progress( (count, t) => {
let ln = Line.fromAngle( space.center, Const.two_pi*t - Const.half_pi, space.size.y/3 );
let c = colors[ count%colors.length ];
- form.strokeOnly( c, 10, "round", "round").line( ln );
+ form.strokeOnly( c, 10, "round", "round" ).line( ln );
form.fillOnly( c ).point( ln.p2, 20, "circle" );
});
// track tempo animation
space.add( tempo );
- // start
+ // For use in demo page only
// Note that `playOnce(200)` will stop after 200ms. Use `play()` to run the animation loop continuously.
space.playOnce(200).bindMouse().bindTouch();
- // For use in demo page only
if (window.registerDemo) window.registerDemo(demoID, space);
})();
\ No newline at end of file
diff --git a/guide/js/examples/tempo_rhythm.js b/guide/js/examples/tempo_rhythm.js
index 7234b321..0244d48d 100644
--- a/guide/js/examples/tempo_rhythm.js
+++ b/guide/js/examples/tempo_rhythm.js
@@ -7,6 +7,8 @@
let space = new CanvasSpace("#"+demoID).setup({ retina: true, bgcolor: "#e2e6ef", resize: true });
let form = space.getForm();
+ // -------
+
// Create tempo instance
let tempo = new Tempo(120);
let counter = 0;
@@ -16,7 +18,7 @@
let tt = Num.cycle( Shaping.cubicInOut( t ) ); // shaping
let right = Line.fromAngle( space.center, -tt * Const.half_pi - Const.half_pi, space.size.y/3 );
let left = Line.fromAngle( space.center, Const.pi+Const.half_pi + tt*Const.half_pi, space.size.y/3 );
- form.strokeOnly( "#123", 10, "round", "round").lines( [left, right] );
+ form.strokeOnly( "#123", 10, "round", "round" ).lines( [left, right] );
if (start) counter++;
let c = (counter % 4 < 2) ? "#62E" : "#0C9"
@@ -26,11 +28,10 @@
// track tempo animation
space.add( tempo );
- // start
+ // For use in demo page only
// Note that `playOnce(200)` will stop after 200ms. Use `play()` to run the animation loop continuously.
space.playOnce(200).bindMouse().bindTouch();
- // For use in demo page only
if (window.registerDemo) window.registerDemo(demoID, space);
})();
\ No newline at end of file
diff --git a/guide/js/examples/tempo_shaping.js b/guide/js/examples/tempo_shaping.js
index dee59a18..d3013b4a 100644
--- a/guide/js/examples/tempo_shaping.js
+++ b/guide/js/examples/tempo_shaping.js
@@ -7,6 +7,8 @@
let space = new CanvasSpace("#"+demoID).setup({ retina: true, bgcolor: "#e2e6ef", resize: true });
let form = space.getForm();
+ // -------
+
// Create tempo instance
let tempo = new Tempo(60);
let colors = ["#62E", "#FFF", "#123"];
@@ -21,18 +23,18 @@
let tt = Shaping.elasticOut( t ); // shaping
let ln = Line.fromAngle( space.center, Const.two_pi*tt - Const.half_pi, space.size.y/3 );
let c = colors[ count%colors.length ];
- form.strokeOnly( c, 10, "round", "round").line( ln );
+ form.strokeOnly( c, 10, "round", "round" ).line( ln );
form.fillOnly( c ).point( ln.p2, 20, "circle" );
});
// track tempo animation
space.add( tempo );
+
- // start
+ // For use in demo page only
// Note that `playOnce(200)` will stop after 200ms. Use `play()` to run the animation loop continuously.
space.playOnce(200).bindMouse().bindTouch();
-
- // For use in demo page only
+
if (window.registerDemo) window.registerDemo(demoID, space);
})();
\ No newline at end of file
diff --git a/guide/js/examples/tempo_stagger.js b/guide/js/examples/tempo_stagger.js
index ad9c17be..ae506a35 100644
--- a/guide/js/examples/tempo_stagger.js
+++ b/guide/js/examples/tempo_stagger.js
@@ -7,6 +7,8 @@
let space = new CanvasSpace("#"+demoID).setup({ retina: true, bgcolor: "#e2e6ef", resize: true });
let form = space.getForm();
+ // -------
+
// Create tempo instance
let tempo = new Tempo(60);
let everyTwo = tempo.every( 2 );
@@ -18,7 +20,7 @@
let dir = (count%2 === 0) ? 1 : -1;
let s = (count%2 !== 0) ? Const.pi : 0;
let ln = Line.fromAngle( space.center, s + Const.pi * tt * dir, space.size.y/3 );
- form.strokeOnly( c, 10, "round", "round").line( ln );
+ form.strokeOnly( c, 10, "round", "round" ).line( ln );
form.fillOnly( c ).point( ln.p2, 20, "circle" );
}
};
@@ -29,11 +31,11 @@
// track tempo animation
space.add( tempo );
- // start
+
+ // For use in demo page only
// Note that `playOnce(200)` will stop after 200ms. Use `play()` to run the animation loop continuously.
space.playOnce(200).bindMouse().bindTouch();
- // For use in demo page only
if (window.registerDemo) window.registerDemo(demoID, space);
})();
\ No newline at end of file
diff --git a/guide/md/_0500_Space.md b/guide/md/_0500_Space.md
index d248bc26..1444ca1c 100644
--- a/guide/md/_0500_Space.md
+++ b/guide/md/_0500_Space.md
@@ -45,7 +45,7 @@ space.add( {
} );
```
-Here we add an object that conforms to the [IPlayer](../docs/interfaces/_space_.iplayer.html) interface, which defines 4 optional callback functions:
+Here we add an object that conforms to the [IPlayer](../docs/?p=Types_IPlayer) interface, which defines 4 optional callback functions:
- `start` function is called when the space is ready. It includes 2 parameters: `bound` which returns the bounding box, and `space` which returns its space.
diff --git a/guide/md/_0700_Animation.md b/guide/md/_0700_Animation.md
index 6bdf1c7a..ff0763c5 100644
--- a/guide/md/_0700_Animation.md
+++ b/guide/md/_0700_Animation.md
@@ -1,10 +1,10 @@
# Animation
-There are many great javascript animation libraries which you may use alongside Pts. For simple use cases, Pts' [`Tempo`](#link) utility class provides an intuitive and lightweight alternative.
+[`Tempo`](#link) is a lightweight utility class which helps you create animation sequences intuitively. It's an alternative to many other great animation libraries (which you can use with Pts too).
-Animation sequences are commonly implemented as a curated list of tweens played in milliseconds. But what if we take the idea one level higher, and think of it like a dance? Like One-two-three, One-two-three...
+Typically, animation sequences are often implemented as a curated list of tweens in milliseconds. But what if we take the idea one level higher, and treat it like a dance? Like One-two-three, One-two-three...
-Let's start by setting the beats. Tempo is usually measured in beats-per-minute (bpm), so there are two ways to initiate a [`Tempo`](#link) instance: by setting a bpm, or specifying the duration of a beat in milliseconds.
+Let's start by counting the beats. Tempo is usually measured in beats-per-minute (bpm), so there are two ways to initiate a [`Tempo`](#link) instance: by setting a bpm, or specifying the duration of a beat in milliseconds.
```
// 120 beats-per-minute, or 500ms per beat
@@ -21,27 +21,29 @@ let everyTwo = tempo.every( 2 ); // count every 2 beats
let everyTen = tempo.every( 10 ); // count every 10 beats
```
-The `every` function returns an object with two chainable functions: `start(...)` and `progress(...)`. The `start` function lets you set a callback to be triggered at the start of every period. For example:
+The `every` function returns an object with two chainable functions: `start(...)` and `progress(...)`. These functions let you attach custom callback functions that respond to animation events.
+
+The `start` function lets you set a callback to be triggered at the start of every *n*-beats period. For example:
```
// at the start of every 2-beats period, do something
everyTwo.start( (count) => ... )
```
-The `progress` function lets you specify a callback during the progress of every period, so you can use it to interpolate values and tween properties.
+The `progress` function lets you set a callback during the progress of every *n*-beats period. The second parameter `t` always start at 0 and ends at 1 in every period, so you can use it to interpolate values and tween properties.
```
// during every 10-beats period, do something
everyTen.progress( (count, t, time, isStart) => ... )
```
-Let's look at an example. Here the tempo is set to 60 BPM (or 1 second per beat), and we design the behaviors as such:
+Let's look at an example. Here the tempo is set to 60 BPM (or 1 second per beat), and we design the behaviors so that:
- Every 1 beat, the square's color changes
- Every 2 beats, the circle's color changes and the rotation completes once
![js:tempo_progress](./assets/bg.png)
-Pretty easy to create sychronized animation sequences, right? Let's try a few more example.
+Pretty easy to create synchronized animation sequences, right? Let's try a few more example.
### Variations
@@ -76,7 +78,7 @@ let custom = tempo.every( [2, 2, 1, 1] ); // Taaa, Taaa, ta-ta.
### Controls
-It's easy to control the speed of your animation by changing bpm by setting the [`Tempo.bpm`](#link) property. This makes it easier to synchronize your animations with music or in specific intervals.
+By changing bpm by setting the [`Tempo.bpm`](#link) property, you can control the speed of your animation. This makes it easier to synchronize your animations with music or at specific intervals.
```
tempo.bpm = 100; // set new bpm
tempo.bpm += 20; // make it 20 beats faster per minute
@@ -86,7 +88,7 @@ Try moving your cursor horizontally to change the bpm in this example:
![js:tempo_control](./assets/bg.png)
-There are two ways to stop an animation. You can either add `return true` in the callback functions, or include a `name` in the third parameter of `start` or `progress` functions.
+There are two ways to stop an animation. You can either `return true` within `start` or `progress` callback functions, or include a `name` in the third parameter of the callbacks and then call `tempo.stop( name )`.
```
let walking = (count, t) => {
diff --git a/src/Util.ts b/src/Util.ts
index 58305ff6..c6f4a2f4 100644
--- a/src/Util.ts
+++ b/src/Util.ts
@@ -376,9 +376,9 @@ export class Tempo {
* The `start` function lets you set a callback on every start. It takes a function ([`ITempoStartFn`](#link)).
* The `progress` function lets you set a callback during progress. It takes a function ([`ITempoProgressFn`](#link)). Both functions let you optionally specify a time offset and a custom name.
* See [Animation guide](../guide/animation-0700.html) for more details.
- * @param beats a rhythm in beats as a number or array of numbers
+ * @param beats a rhythm in beats as a number or an array of numbers
* @example `tempo.every(2).start( (count) => ... )`, `tempo.every([2,4,6]).progress( (count, t) => ... )`
- * @returns a object with chainable functions
+ * @returns an object with chainable functions
*/
every( beats:number|number[] ):ITempoResponses {
let self = this;