implement pinch to zoom
This commit is contained in:
+2
@@ -0,0 +1,2 @@
|
||||
components
|
||||
build
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
|
||||
1.2.0 / 2015-03-16
|
||||
==================
|
||||
|
||||
* update "emitter" to v1.2.0
|
||||
* use "component-clone" and "component-type" for browsers support (#5, @cristiandouce)
|
||||
* update component.json (#4, @pgherveou)
|
||||
* package: add browserify mappings (#7, @dfcreative)
|
||||
* package: add "repository" field (#3)
|
||||
|
||||
1.1.0 / 2013-05-29
|
||||
==================
|
||||
|
||||
* add Tween#stop(). Closes #2
|
||||
* fix final update to complete the tween. Closes #1
|
||||
|
||||
1.0.0 / 2013-05-27
|
||||
==================
|
||||
|
||||
* pin deps
|
||||
* add package.json
|
||||
* add interactive example
|
||||
|
||||
0.1.0 / 2012-11-10
|
||||
==================
|
||||
|
||||
* add array tweening support
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
|
||||
build: components index.js
|
||||
@component build --dev
|
||||
|
||||
components: component.json
|
||||
@component install --dev
|
||||
|
||||
clean:
|
||||
rm -fr build components template.js
|
||||
|
||||
tween.js:
|
||||
@component build --standalone tween \
|
||||
&& mv build/build.js $@ \
|
||||
&& rm -fr build
|
||||
|
||||
.PHONY: clean tween.js
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
|
||||
# tween
|
||||
|
||||
Motion tween component using [ease](https://github.com/component/ease).
|
||||
|
||||
## Installation
|
||||
|
||||
$ component install component/tween
|
||||
|
||||
## Example
|
||||
|
||||
```js
|
||||
var Tween = require('tween');
|
||||
var raf = require('raf');
|
||||
var button = document.querySelector('button');
|
||||
|
||||
var tween = Tween({ rotate: 0, opacity: 0 })
|
||||
.ease('out-bounce')
|
||||
.to({ rotate: 360, opacity: 1 })
|
||||
.duration(800);
|
||||
|
||||
tween.update(function(o){
|
||||
button.style.opacity = o.opacity;
|
||||
button.style.webkitTransform = 'rotate(' + (o.rotate | 0) + 'deg)';
|
||||
});
|
||||
|
||||
tween.on('end', function(){
|
||||
animate = function(){};
|
||||
});
|
||||
|
||||
function animate() {
|
||||
raf(animate);
|
||||
tween.update();
|
||||
}
|
||||
|
||||
animate();
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Tween(obj:Object|Array)
|
||||
|
||||
Initialize a new `Tween` with `obj`.
|
||||
|
||||
### Tween#reset()
|
||||
|
||||
Reset the tween.
|
||||
|
||||
### Tween#to(obj:Object|Array)
|
||||
|
||||
Tween to `obj` and reset internal state.
|
||||
|
||||
tween.to({ x: 50, y: 100 })
|
||||
|
||||
### Tween#duration(ms:Number)
|
||||
|
||||
Set duration to `ms` [500].
|
||||
|
||||
### Tween#ease(fn:String|Function)
|
||||
|
||||
Set easing function to `fn`.
|
||||
|
||||
tween.ease('in-out-sine')
|
||||
|
||||
### Tween#update(fn:Function)
|
||||
|
||||
Set update function to `fn` or
|
||||
when no argument is given this performs
|
||||
a "step".
|
||||
|
||||
### Tween#stop()
|
||||
|
||||
Immediately stop the tween and emit "stop" and end" events. `tween.stopped`
|
||||
is then marked as `true`.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "tween",
|
||||
"repo": "component/tween",
|
||||
"description": "Motion tween engine using 'ease'",
|
||||
"version": "1.2.0",
|
||||
"keywords": [
|
||||
"tween",
|
||||
"tweening",
|
||||
"animation"
|
||||
],
|
||||
"dependencies": {
|
||||
"component/clone": "0.2.2",
|
||||
"component/ease": "1.0.0",
|
||||
"component/emitter": "1.2.0",
|
||||
"component/type": "1.1.0"
|
||||
},
|
||||
"development": {
|
||||
"component/raf": "*",
|
||||
"component/autoscale-canvas": "*"
|
||||
},
|
||||
"license": "MIT",
|
||||
"scripts": [
|
||||
"index.js"
|
||||
]
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
|
||||
<style>
|
||||
canvas {
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="../build/build.js"></script>
|
||||
|
||||
<canvas width=1000 height=500></canvas>
|
||||
|
||||
<script>
|
||||
var Tween = require('tween');
|
||||
var raf = require('component-raf');
|
||||
var canvas = document.querySelector('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
var h = 500;
|
||||
|
||||
function random(n, f) {
|
||||
var arr = [];
|
||||
while (n--) arr.push(Math.random() * f);
|
||||
return arr;
|
||||
}
|
||||
|
||||
var tween = Tween(random(1000, 50))
|
||||
.ease('out-bounce')
|
||||
.to(random(1000, 400))
|
||||
.duration(800);
|
||||
|
||||
tween.update(function(a){
|
||||
canvas.width = canvas.width;
|
||||
ctx.fillStyle = '#0070ff';
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
ctx.fillRect(i, h - a[i], 1, a[i]);
|
||||
}
|
||||
});
|
||||
|
||||
tween.on('end', function(){
|
||||
animate = function(){};
|
||||
});
|
||||
|
||||
function animate() {
|
||||
raf(animate);
|
||||
tween.update();
|
||||
}
|
||||
|
||||
animate();
|
||||
</script>
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
|
||||
<style>
|
||||
canvas {
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="../build/build.js"></script>
|
||||
|
||||
<canvas width=500 height=400></canvas>
|
||||
|
||||
<script>
|
||||
var Tween = require('tween');
|
||||
var raf = require('component-raf');
|
||||
var canvas = document.querySelector('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
var w = canvas.width, h = canvas.height;
|
||||
|
||||
var tween = Tween({ x: w/2, y: 20, r: 10, a: .5 })
|
||||
.ease('out-bounce')
|
||||
.to({ x: w/2, y: h-8, r: 10, a: .5 })
|
||||
.duration(2000);
|
||||
|
||||
tween.update(function(o){
|
||||
canvas.width = canvas.width;
|
||||
ctx.fillStyle = 'red';
|
||||
ctx.globalAlpha = o.a;
|
||||
ctx.arc(o.x | 0, o.y | 0, o.r, 0, Math.PI * 2, false);
|
||||
ctx.fill();
|
||||
});
|
||||
|
||||
var n = 0;
|
||||
tween.on('end', function(){
|
||||
switch (n++) {
|
||||
case 0:
|
||||
tween
|
||||
.to({ x: w/2, y: 20, r: 10, a: .5 })
|
||||
.ease('out-sine')
|
||||
.duration(500);
|
||||
break;
|
||||
case 1:
|
||||
tween
|
||||
.to({ x: w/2, y: h/2, r: 10, a: .5 })
|
||||
.ease('in-out-back')
|
||||
.duration(800);
|
||||
break;
|
||||
case 2:
|
||||
tween
|
||||
.to({ x: w/2, y: h/2, r: 80, a: 1 })
|
||||
.ease('out-bounce')
|
||||
.duration(1500);
|
||||
break;
|
||||
default:
|
||||
animate = function(){};
|
||||
}
|
||||
});
|
||||
|
||||
function animate() {
|
||||
raf(animate);
|
||||
tween.update();
|
||||
}
|
||||
|
||||
animate();
|
||||
</script>
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
|
||||
<style>
|
||||
canvas {
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="../build/build.js"></script>
|
||||
|
||||
<canvas width=500 height=400></canvas>
|
||||
|
||||
<button onclick='tween.stop()'>Stop</button>
|
||||
|
||||
<script>
|
||||
var Tween = require('tween');
|
||||
var raf = require('component-raf');
|
||||
var canvas = document.querySelector('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
var tween = Tween({ alpha: 0, border: 1, radius: 1 })
|
||||
.ease('out-bounce')
|
||||
.to({ alpha: 1, border: 15, radius: 150 })
|
||||
.duration(1000);
|
||||
|
||||
tween.update(function(o){
|
||||
canvas.width = canvas.width;
|
||||
ctx.strokeStyle = 'black';
|
||||
ctx.globalAlpha = o.alpha;
|
||||
ctx.lineWidth = o.border;
|
||||
ctx.arc(canvas.width / 2, canvas.height / 2, o.radius, 0, Math.PI * 2, false);
|
||||
ctx.stroke();
|
||||
ctx.fill();
|
||||
});
|
||||
|
||||
tween.on('end', function(){
|
||||
animate = function(){};
|
||||
});
|
||||
|
||||
function animate() {
|
||||
raf(animate);
|
||||
tween.update();
|
||||
}
|
||||
|
||||
animate();
|
||||
</script>
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
|
||||
<style>
|
||||
body {
|
||||
padding: 50px;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 15px 25px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<button>Button</button>
|
||||
|
||||
<script src="../build/build.js"></script>
|
||||
|
||||
<script>
|
||||
var Tween = require('tween');
|
||||
var raf = require('component-raf');
|
||||
var button = document.querySelector('button');
|
||||
|
||||
var tween = Tween({ rotate: 0, opacity: 0 })
|
||||
.ease('out-bounce')
|
||||
.to({ rotate: 360, opacity: 1 })
|
||||
.duration(800);
|
||||
|
||||
tween.update(function(o){
|
||||
button.style.opacity = o.opacity;
|
||||
button.style.webkitTransform = 'rotate(' + (o.rotate | 0) + 'deg)';
|
||||
});
|
||||
|
||||
tween.on('end', function(){
|
||||
animate = function(){};
|
||||
});
|
||||
|
||||
function animate() {
|
||||
raf(animate);
|
||||
tween.update();
|
||||
}
|
||||
|
||||
animate();
|
||||
</script>
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
|
||||
<style>
|
||||
canvas {
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="../build/build.js"></script>
|
||||
|
||||
<canvas width=500 height=400></canvas>
|
||||
|
||||
<script>
|
||||
var Tween = require('tween');
|
||||
var raf = require('component-raf');
|
||||
var canvas = document.querySelector('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
var w = canvas.width, h = canvas.height;
|
||||
|
||||
function Ball(x, y) {
|
||||
this.moveTo(x, y);
|
||||
this.rad = 10;
|
||||
}
|
||||
|
||||
Ball.prototype.moveTo = function(x, y){
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
};
|
||||
|
||||
Ball.prototype.draw = function(ctx){
|
||||
ctx.save();
|
||||
ctx.fillStyle = 'red';
|
||||
ctx.arc(this.x | 0, this.y | 0, this.rad, 0, Math.PI * 2, false);
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
};
|
||||
|
||||
var ball = new Ball(100, 100);
|
||||
ball.draw(ctx);
|
||||
|
||||
canvas.onclick = function(e){
|
||||
console.log('move');
|
||||
|
||||
var tween = Tween({ x: ball.x, y: ball.y })
|
||||
.ease('out-bounce')
|
||||
.to({ x: e.offsetX, y: e.offsetY })
|
||||
.duration(1500);
|
||||
|
||||
tween.update(function(o){
|
||||
canvas.width = canvas.width;
|
||||
ball.moveTo(o.x, o.y);
|
||||
ball.draw(ctx);
|
||||
});
|
||||
|
||||
function animate() {
|
||||
raf(animate);
|
||||
tween.update();
|
||||
}
|
||||
|
||||
animate();
|
||||
};
|
||||
|
||||
</script>
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
|
||||
<style>
|
||||
canvas {
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="../build/build.js"></script>
|
||||
|
||||
<canvas width=500 height=400></canvas>
|
||||
|
||||
<script>
|
||||
var Tween = require('tween');
|
||||
var raf = require('component-raf');
|
||||
var canvas = document.querySelector('canvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
var tween = Tween({ w: 1, h: 1, border: 1, alpha: 0 })
|
||||
.ease('out-circ')
|
||||
.to({ border: 5, w: 150, h: 100, alpha: 1 })
|
||||
.duration(800);
|
||||
|
||||
tween.update(function(o){
|
||||
canvas.width = canvas.width;
|
||||
ctx.strokeStyle = 'black';
|
||||
ctx.globalAlpha = o.alpha;
|
||||
ctx.lineWidth = o.border;
|
||||
ctx.rect(canvas.width / 2 - o.w / 2, canvas.height / 2 - o.h / 2, o.w, o.h);
|
||||
ctx.stroke();
|
||||
ctx.fill();
|
||||
});
|
||||
|
||||
tween.on('end', function(){
|
||||
animate = function(){};
|
||||
});
|
||||
|
||||
function animate() {
|
||||
raf(animate);
|
||||
tween.update();
|
||||
}
|
||||
|
||||
animate();
|
||||
</script>
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Emitter = require('emitter');
|
||||
var clone = require('clone');
|
||||
var type = require('type');
|
||||
var ease = require('ease');
|
||||
|
||||
/**
|
||||
* Expose `Tween`.
|
||||
*/
|
||||
|
||||
module.exports = Tween;
|
||||
|
||||
/**
|
||||
* Initialize a new `Tween` with `obj`.
|
||||
*
|
||||
* @param {Object|Array} obj
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Tween(obj) {
|
||||
if (!(this instanceof Tween)) return new Tween(obj);
|
||||
this._from = obj;
|
||||
this.ease('linear');
|
||||
this.duration(500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mixin emitter.
|
||||
*/
|
||||
|
||||
Emitter(Tween.prototype);
|
||||
|
||||
/**
|
||||
* Reset the tween.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Tween.prototype.reset = function(){
|
||||
this.isArray = 'array' === type(this._from);
|
||||
this._curr = clone(this._from);
|
||||
this._done = false;
|
||||
this._start = Date.now();
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tween to `obj` and reset internal state.
|
||||
*
|
||||
* tween.to({ x: 50, y: 100 })
|
||||
*
|
||||
* @param {Object|Array} obj
|
||||
* @return {Tween} self
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Tween.prototype.to = function(obj){
|
||||
this.reset();
|
||||
this._to = obj;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set duration to `ms` [500].
|
||||
*
|
||||
* @param {Number} ms
|
||||
* @return {Tween} self
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Tween.prototype.duration = function(ms){
|
||||
this._duration = ms;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set easing function to `fn`.
|
||||
*
|
||||
* tween.ease('in-out-sine')
|
||||
*
|
||||
* @param {String|Function} fn
|
||||
* @return {Tween}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Tween.prototype.ease = function(fn){
|
||||
fn = 'function' == typeof fn ? fn : ease[fn];
|
||||
if (!fn) throw new TypeError('invalid easing function');
|
||||
this._ease = fn;
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop the tween and immediately emit "stop" and "end".
|
||||
*
|
||||
* @return {Tween}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Tween.prototype.stop = function(){
|
||||
this.stopped = true;
|
||||
this._done = true;
|
||||
this.emit('stop');
|
||||
this.emit('end');
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Perform a step.
|
||||
*
|
||||
* @return {Tween} self
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Tween.prototype.step = function(){
|
||||
if (this._done) return;
|
||||
|
||||
// duration
|
||||
var duration = this._duration;
|
||||
var now = Date.now();
|
||||
var delta = now - this._start;
|
||||
var done = delta >= duration;
|
||||
|
||||
// complete
|
||||
if (done) {
|
||||
this._from = this._to;
|
||||
this._update(this._to);
|
||||
this._done = true;
|
||||
this.emit('end');
|
||||
return this;
|
||||
}
|
||||
|
||||
// tween
|
||||
var from = this._from;
|
||||
var to = this._to;
|
||||
var curr = this._curr;
|
||||
var fn = this._ease;
|
||||
var p = (now - this._start) / duration;
|
||||
var n = fn(p);
|
||||
|
||||
// array
|
||||
if (this.isArray) {
|
||||
for (var i = 0; i < from.length; ++i) {
|
||||
curr[i] = from[i] + (to[i] - from[i]) * n;
|
||||
}
|
||||
|
||||
this._update(curr);
|
||||
return this;
|
||||
}
|
||||
|
||||
// objech
|
||||
for (var k in from) {
|
||||
curr[k] = from[k] + (to[k] - from[k]) * n;
|
||||
}
|
||||
|
||||
this._update(curr);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set update function to `fn` or
|
||||
* when no argument is given this performs
|
||||
* a "step".
|
||||
*
|
||||
* @param {Function} fn
|
||||
* @return {Tween} self
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Tween.prototype.update = function(fn){
|
||||
if (0 == arguments.length) return this.step();
|
||||
this._update = fn;
|
||||
return this;
|
||||
};
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
|
||||
1.2.0 / 2014-02-12
|
||||
==================
|
||||
|
||||
* prefix events with `$` to support object prototype method names
|
||||
|
||||
1.1.3 / 2014-06-20
|
||||
==================
|
||||
|
||||
* republish for npm
|
||||
* add LICENSE file
|
||||
|
||||
1.1.2 / 2014-02-10
|
||||
==================
|
||||
|
||||
* package: rename to "component-emitter"
|
||||
* package: update "main" and "component" fields
|
||||
* Add license to Readme (same format as the other components)
|
||||
* created .npmignore
|
||||
* travis stuff
|
||||
|
||||
1.1.1 / 2013-12-01
|
||||
==================
|
||||
|
||||
* fix .once adding .on to the listener
|
||||
* docs: Emitter#off()
|
||||
* component: add `.repo` prop
|
||||
|
||||
1.1.0 / 2013-10-20
|
||||
==================
|
||||
|
||||
* add `.addEventListener()` and `.removeEventListener()` aliases
|
||||
|
||||
1.0.1 / 2013-06-27
|
||||
==================
|
||||
|
||||
* add support for legacy ie
|
||||
|
||||
1.0.0 / 2013-02-26
|
||||
==================
|
||||
|
||||
* add `.off()` support for removing all listeners
|
||||
|
||||
0.0.6 / 2012-10-08
|
||||
==================
|
||||
|
||||
* add `this._callbacks` initialization to prevent funky gotcha
|
||||
|
||||
0.0.5 / 2012-09-07
|
||||
==================
|
||||
|
||||
* fix `Emitter.call(this)` usage
|
||||
|
||||
0.0.3 / 2012-07-11
|
||||
==================
|
||||
|
||||
* add `.listeners()`
|
||||
* rename `.has()` to `.hasListeners()`
|
||||
|
||||
0.0.2 / 2012-06-28
|
||||
==================
|
||||
|
||||
* fix `.off()` with `.once()`-registered callbacks
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014 Component contributors <dev@component.io>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
# Emitter [](https://travis-ci.org/component/emitter)
|
||||
|
||||
Event emitter component.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ component install component/emitter
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Emitter(obj)
|
||||
|
||||
The `Emitter` may also be used as a mixin. For example
|
||||
a "plain" object may become an emitter, or you may
|
||||
extend an existing prototype.
|
||||
|
||||
As an `Emitter` instance:
|
||||
|
||||
```js
|
||||
var Emitter = require('emitter');
|
||||
var emitter = new Emitter;
|
||||
emitter.emit('something');
|
||||
```
|
||||
|
||||
As a mixin:
|
||||
|
||||
```js
|
||||
var Emitter = require('emitter');
|
||||
var user = { name: 'tobi' };
|
||||
Emitter(user);
|
||||
|
||||
user.emit('im a user');
|
||||
```
|
||||
|
||||
As a prototype mixin:
|
||||
|
||||
```js
|
||||
var Emitter = require('emitter');
|
||||
Emitter(User.prototype);
|
||||
```
|
||||
|
||||
### Emitter#on(event, fn)
|
||||
|
||||
Register an `event` handler `fn`.
|
||||
|
||||
### Emitter#once(event, fn)
|
||||
|
||||
Register a single-shot `event` handler `fn`,
|
||||
removed immediately after it is invoked the
|
||||
first time.
|
||||
|
||||
### Emitter#off(event, fn)
|
||||
|
||||
* Pass `event` and `fn` to remove a listener.
|
||||
* Pass `event` to remove all listeners on that event.
|
||||
* Pass nothing to remove all listeners on all events.
|
||||
|
||||
### Emitter#emit(event, ...)
|
||||
|
||||
Emit an `event` with variable option args.
|
||||
|
||||
### Emitter#listeners(event)
|
||||
|
||||
Return an array of callbacks, or an empty array.
|
||||
|
||||
### Emitter#hasListeners(event)
|
||||
|
||||
Check if this emitter has `event` handlers.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
|
||||
/**
|
||||
* Expose `Emitter`.
|
||||
*/
|
||||
|
||||
module.exports = Emitter;
|
||||
|
||||
/**
|
||||
* Initialize a new `Emitter`.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Emitter(obj) {
|
||||
if (obj) return mixin(obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* Mixin the emitter properties.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function mixin(obj) {
|
||||
for (var key in Emitter.prototype) {
|
||||
obj[key] = Emitter.prototype[key];
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen on the given `event` with `fn`.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.on =
|
||||
Emitter.prototype.addEventListener = function(event, fn){
|
||||
this._callbacks = this._callbacks || {};
|
||||
(this._callbacks['$' + event] = this._callbacks['$' + event] || [])
|
||||
.push(fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an `event` listener that will be invoked a single
|
||||
* time then automatically removed.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.once = function(event, fn){
|
||||
function on() {
|
||||
this.off(event, on);
|
||||
fn.apply(this, arguments);
|
||||
}
|
||||
|
||||
on.fn = fn;
|
||||
this.on(event, on);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the given callback for `event` or all
|
||||
* registered callbacks.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.off =
|
||||
Emitter.prototype.removeListener =
|
||||
Emitter.prototype.removeAllListeners =
|
||||
Emitter.prototype.removeEventListener = function(event, fn){
|
||||
this._callbacks = this._callbacks || {};
|
||||
|
||||
// all
|
||||
if (0 == arguments.length) {
|
||||
this._callbacks = {};
|
||||
return this;
|
||||
}
|
||||
|
||||
// specific event
|
||||
var callbacks = this._callbacks['$' + event];
|
||||
if (!callbacks) return this;
|
||||
|
||||
// remove all handlers
|
||||
if (1 == arguments.length) {
|
||||
delete this._callbacks['$' + event];
|
||||
return this;
|
||||
}
|
||||
|
||||
// remove specific handler
|
||||
var cb;
|
||||
for (var i = 0; i < callbacks.length; i++) {
|
||||
cb = callbacks[i];
|
||||
if (cb === fn || cb.fn === fn) {
|
||||
callbacks.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Emit `event` with the given args.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Mixed} ...
|
||||
* @return {Emitter}
|
||||
*/
|
||||
|
||||
Emitter.prototype.emit = function(event){
|
||||
this._callbacks = this._callbacks || {};
|
||||
var args = [].slice.call(arguments, 1)
|
||||
, callbacks = this._callbacks['$' + event];
|
||||
|
||||
if (callbacks) {
|
||||
callbacks = callbacks.slice(0);
|
||||
for (var i = 0, len = callbacks.length; i < len; ++i) {
|
||||
callbacks[i].apply(this, args);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return array of callbacks for `event`.
|
||||
*
|
||||
* @param {String} event
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.listeners = function(event){
|
||||
this._callbacks = this._callbacks || {};
|
||||
return this._callbacks['$' + event] || [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if this emitter has `event` handlers.
|
||||
*
|
||||
* @param {String} event
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.hasListeners = function(event){
|
||||
return !! this.listeners(event).length;
|
||||
};
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "component-emitter",
|
||||
"description": "Event emitter",
|
||||
"version": "1.2.0",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"mocha": "*",
|
||||
"should": "*"
|
||||
},
|
||||
"component": {
|
||||
"scripts": {
|
||||
"emitter/index.js": "index.js"
|
||||
}
|
||||
},
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/component/emitter.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
},
|
||||
"files": ["index.js", "LICENSE"]
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "component-tween",
|
||||
"description": "Motion tween engine using 'ease'",
|
||||
"version": "1.2.0",
|
||||
"keywords": [
|
||||
"tween",
|
||||
"tweening",
|
||||
"animation"
|
||||
],
|
||||
"dependencies": {
|
||||
"component-clone": "0.2.2",
|
||||
"component-emitter": "1.2.0",
|
||||
"component-type": "1.1.0",
|
||||
"ease-component": "1.0.0"
|
||||
},
|
||||
"browser": {
|
||||
"clone": "component-clone",
|
||||
"emitter": "component-emitter",
|
||||
"type": "component-type",
|
||||
"ease": "ease-component"
|
||||
},
|
||||
"license": "MIT",
|
||||
"component": {
|
||||
"scripts": {
|
||||
"tween/index.js": "index.js"
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/component/tween.git"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user