nanotween
Advanced tools
Comparing version 0.3.0 to 0.4.0
@@ -7,19 +7,8 @@ var uptime = require('nanouptime'); | ||
function tick(tween, diff) { | ||
if (!tween.state.isRunning) return | ||
var progress = tween.state.progress + diff / tween._options.duration; | ||
if (progress > 1) { | ||
while (progress > 1) { | ||
if (!tween.state.isRunning) return | ||
tween.complete(); | ||
progress--; | ||
} | ||
} else { | ||
tween.set(progress); | ||
} | ||
} | ||
function Tween() { | ||
var self = this; | ||
function Tween() { | ||
this._options = { | ||
self._options = { | ||
id: tweens.length, | ||
delay: 0, | ||
repeats: 1, | ||
@@ -34,3 +23,3 @@ duration: 0, | ||
this.state = { | ||
self.state = { | ||
isRunning: false, | ||
@@ -42,4 +31,2 @@ current: void 0, | ||
var self = this; | ||
function remaining() { | ||
@@ -54,98 +41,116 @@ return { | ||
this.bus = new NanoEvents(); | ||
self.bus = new NanoEvents(); | ||
tweens.push(this); | ||
tweens.push(self); | ||
this.use = function(enhancer) { | ||
enhancer(this); | ||
return this | ||
self.use = function(enhancer) { | ||
enhancer(self); | ||
return self | ||
}; | ||
this.easing = function(easing) { | ||
this._options.easing = easing; | ||
return this | ||
self.easing = function(easing) { | ||
self._options.easing = easing; | ||
return self | ||
}; | ||
this.duration = function(duration) { | ||
this._options.duration = duration; | ||
return this | ||
self.duration = function(duration) { | ||
self._options.duration = duration; | ||
return self | ||
}; | ||
this.repeat = function(repeat) { | ||
this._options.repeats = repeat; | ||
return this | ||
self.delay = function(delay) { | ||
self._options.delay = delay; | ||
return self | ||
}; | ||
this.reverse = function(val) { | ||
this._options.reversed = val !== void 0 ? val : !this._options.reversed; | ||
this.state.progress = 1 - this.state.progress; | ||
return this | ||
self.repeat = function(repeat) { | ||
self._options.repeats = repeat; | ||
return self | ||
}; | ||
this.on = function(evt, cb) { | ||
this.bus.on(evt, cb); | ||
return this | ||
self.reverse = function(val) { | ||
self._options.reversed = val !== void 0 ? val : !self._options.reversed; | ||
self.state.progress = 1 - self.state.progress; | ||
return self | ||
}; | ||
this.convert = function(cb) { | ||
this._options.converters.push(cb); | ||
return this | ||
self.on = function(evt, cb) { | ||
self.bus.on(evt, cb); | ||
return self | ||
}; | ||
this.set = function(progress) { | ||
this.state.progress = progress; | ||
var easing = this._options.easing; | ||
self.convert = function(cb) { | ||
self._options.converters.push(cb); | ||
return self | ||
}; | ||
self.set = function(progress) { | ||
if (progress > 1) { | ||
var times = Math.floor(progress); | ||
self.complete(times); | ||
if (!self.state.isRunning) return | ||
self._rescale(progress - times); | ||
} else { | ||
self._rescale(progress); | ||
} | ||
return self | ||
}; | ||
self._rescale = function(progress) { | ||
self.state.progress = progress; | ||
var easing = self._options.easing; | ||
easing.reverse = easing.reverse || easing; | ||
var value = this._options.reversed | ||
? 1 - easing.reverse(this.state.progress) | ||
: easing(this.state.progress); | ||
this.state.value = this._options.converters.reduce(function(res, cb) { | ||
var value = self._options.reversed | ||
? 1 - easing.reverse(self.state.progress) | ||
: easing(self.state.progress); | ||
self.state.value = self._options.converters.reduce(function(res, cb) { | ||
return cb(res) | ||
}, value); | ||
this.bus.emit('update', this.state.value); | ||
self.bus.emit('update', self.state.value); | ||
}; | ||
this.start = function() { | ||
this.set(0); | ||
this.state.repeats = this._options.repeats - 1; | ||
this.state.isRunning = true; | ||
this.bus.emit('start'); | ||
return this | ||
self.start = function() { | ||
self._i = setTimeout(function() { | ||
self.set(0); | ||
self.state.repeats = self._options.repeats - 1; | ||
self.state.isRunning = true; | ||
self.bus.emit('start'); | ||
}, self._options.delay); | ||
return self | ||
}; | ||
this.stop = function() { | ||
this.set(1); | ||
this.state.repeats = 0; | ||
this.state.isRunning = false; | ||
this.bus.emit('stop'); | ||
return this | ||
self.stop = function() { | ||
self.set(1); | ||
self.state.repeats = 0; | ||
self.state.isRunning = false; | ||
self.bus.emit('stop'); | ||
return self | ||
}; | ||
this.complete = function() { | ||
if (this.state.repeats > 0) { | ||
this.state.repeats--; | ||
this.set(1); | ||
setTimeout(function() { | ||
self.bus.emit('step', remaining()); | ||
self.set(0); | ||
}, 0); | ||
} else { | ||
this.state.isRunning = false; | ||
this.set(1); | ||
setTimeout(function() { | ||
self.bus.emit('complete'); | ||
}, 0); | ||
self.complete = function(times) { | ||
self._rescale(1); | ||
var isStop = self.state.repeats < times; | ||
var ticks = isStop ? self.state.repeats : times; | ||
while (ticks > 0) { | ||
self.state.repeats--; | ||
self.bus.emit('step', ticks); | ||
ticks--; | ||
} | ||
if (isStop) { | ||
self.state.isRunning = false; | ||
self.bus.emit('complete'); | ||
} | ||
return self | ||
}; | ||
this.play = function() { | ||
this.state.isRunning = true; | ||
this.bus.emit('play', remaining()); | ||
return this | ||
self.play = function() { | ||
self.state.isRunning = true; | ||
self.bus.emit('play', remaining()); | ||
return self | ||
}; | ||
this.pause = function() { | ||
this.state.isRunning = false; | ||
this.bus.emit('pause', remaining()); | ||
return this | ||
self.pause = function() { | ||
self.state.isRunning = false; | ||
self.bus.emit('pause', remaining()); | ||
return self | ||
}; | ||
@@ -155,5 +160,10 @@ } | ||
Tween.update = function() { | ||
if (document.hidden) return | ||
var now = uptime(); | ||
tweens.forEach(function(tween) { | ||
if (tween.state.isRunning) tick(tween, now - lastTime); | ||
if (tween.state.isRunning) { | ||
tween.set( | ||
tween.state.progress + (now - lastTime) / tween._options.duration | ||
); | ||
} | ||
}); | ||
@@ -160,0 +170,0 @@ lastTime = now; |
180
index.js
@@ -7,19 +7,8 @@ import uptime from 'nanouptime' | ||
function tick(tween, diff) { | ||
if (!tween.state.isRunning) return | ||
var progress = tween.state.progress + diff / tween._options.duration | ||
if (progress > 1) { | ||
while (progress > 1) { | ||
if (!tween.state.isRunning) return | ||
tween.complete() | ||
progress-- | ||
} | ||
} else { | ||
tween.set(progress) | ||
} | ||
} | ||
export default function Tween() { | ||
var self = this | ||
export default function Tween() { | ||
this._options = { | ||
self._options = { | ||
id: tweens.length, | ||
delay: 0, | ||
repeats: 1, | ||
@@ -34,3 +23,3 @@ duration: 0, | ||
this.state = { | ||
self.state = { | ||
isRunning: false, | ||
@@ -42,4 +31,2 @@ current: void 0, | ||
var self = this | ||
function remaining() { | ||
@@ -54,98 +41,116 @@ return { | ||
this.bus = new NanoEvents() | ||
self.bus = new NanoEvents() | ||
tweens.push(this) | ||
tweens.push(self) | ||
this.use = function(enhancer) { | ||
enhancer(this) | ||
return this | ||
self.use = function(enhancer) { | ||
enhancer(self) | ||
return self | ||
} | ||
this.easing = function(easing) { | ||
this._options.easing = easing | ||
return this | ||
self.easing = function(easing) { | ||
self._options.easing = easing | ||
return self | ||
} | ||
this.duration = function(duration) { | ||
this._options.duration = duration | ||
return this | ||
self.duration = function(duration) { | ||
self._options.duration = duration | ||
return self | ||
} | ||
this.repeat = function(repeat) { | ||
this._options.repeats = repeat | ||
return this | ||
self.delay = function(delay) { | ||
self._options.delay = delay | ||
return self | ||
} | ||
this.reverse = function(val) { | ||
this._options.reversed = val !== void 0 ? val : !this._options.reversed | ||
this.state.progress = 1 - this.state.progress | ||
return this | ||
self.repeat = function(repeat) { | ||
self._options.repeats = repeat | ||
return self | ||
} | ||
this.on = function(evt, cb) { | ||
this.bus.on(evt, cb) | ||
return this | ||
self.reverse = function(val) { | ||
self._options.reversed = val !== void 0 ? val : !self._options.reversed | ||
self.state.progress = 1 - self.state.progress | ||
return self | ||
} | ||
this.convert = function(cb) { | ||
this._options.converters.push(cb) | ||
return this | ||
self.on = function(evt, cb) { | ||
self.bus.on(evt, cb) | ||
return self | ||
} | ||
this.set = function(progress) { | ||
this.state.progress = progress | ||
var easing = this._options.easing | ||
self.convert = function(cb) { | ||
self._options.converters.push(cb) | ||
return self | ||
} | ||
self.set = function(progress) { | ||
if (progress > 1) { | ||
var times = Math.floor(progress) | ||
self.complete(times) | ||
if (!self.state.isRunning) return | ||
self._rescale(progress - times) | ||
} else { | ||
self._rescale(progress) | ||
} | ||
return self | ||
} | ||
self._rescale = function(progress) { | ||
self.state.progress = progress | ||
var easing = self._options.easing | ||
easing.reverse = easing.reverse || easing | ||
var value = this._options.reversed | ||
? 1 - easing.reverse(this.state.progress) | ||
: easing(this.state.progress) | ||
this.state.value = this._options.converters.reduce(function(res, cb) { | ||
var value = self._options.reversed | ||
? 1 - easing.reverse(self.state.progress) | ||
: easing(self.state.progress) | ||
self.state.value = self._options.converters.reduce(function(res, cb) { | ||
return cb(res) | ||
}, value) | ||
this.bus.emit('update', this.state.value) | ||
self.bus.emit('update', self.state.value) | ||
} | ||
this.start = function() { | ||
this.set(0) | ||
this.state.repeats = this._options.repeats - 1 | ||
this.state.isRunning = true | ||
this.bus.emit('start') | ||
return this | ||
self.start = function() { | ||
self._i = setTimeout(function() { | ||
self.set(0) | ||
self.state.repeats = self._options.repeats - 1 | ||
self.state.isRunning = true | ||
self.bus.emit('start') | ||
}, self._options.delay) | ||
return self | ||
} | ||
this.stop = function() { | ||
this.set(1) | ||
this.state.repeats = 0 | ||
this.state.isRunning = false | ||
this.bus.emit('stop') | ||
return this | ||
self.stop = function() { | ||
self.set(1) | ||
self.state.repeats = 0 | ||
self.state.isRunning = false | ||
self.bus.emit('stop') | ||
return self | ||
} | ||
this.complete = function() { | ||
if (this.state.repeats > 0) { | ||
this.state.repeats-- | ||
this.set(1) | ||
setTimeout(function() { | ||
self.bus.emit('step', remaining()) | ||
self.set(0) | ||
}, 0) | ||
} else { | ||
this.state.isRunning = false | ||
this.set(1) | ||
setTimeout(function() { | ||
self.bus.emit('complete') | ||
}, 0) | ||
self.complete = function(times) { | ||
self._rescale(1) | ||
var isStop = self.state.repeats < times | ||
var ticks = isStop ? self.state.repeats : times | ||
while (ticks > 0) { | ||
self.state.repeats-- | ||
self.bus.emit('step', ticks) | ||
ticks-- | ||
} | ||
if (isStop) { | ||
self.state.isRunning = false | ||
self.bus.emit('complete') | ||
} | ||
return self | ||
} | ||
this.play = function() { | ||
this.state.isRunning = true | ||
this.bus.emit('play', remaining()) | ||
return this | ||
self.play = function() { | ||
self.state.isRunning = true | ||
self.bus.emit('play', remaining()) | ||
return self | ||
} | ||
this.pause = function() { | ||
this.state.isRunning = false | ||
this.bus.emit('pause', remaining()) | ||
return this | ||
self.pause = function() { | ||
self.state.isRunning = false | ||
self.bus.emit('pause', remaining()) | ||
return self | ||
} | ||
@@ -155,7 +160,12 @@ } | ||
Tween.update = function() { | ||
if (document.hidden) return | ||
var now = uptime() | ||
tweens.forEach(function(tween) { | ||
if (tween.state.isRunning) tick(tween, now - lastTime) | ||
if (tween.state.isRunning) { | ||
tween.set( | ||
tween.state.progress + (now - lastTime) / tween._options.duration | ||
) | ||
} | ||
}) | ||
lastTime = now | ||
} |
{ | ||
"name": "nanotween", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"description": "Tiny library for tweening", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
# NanoTween | ||
1.5 KB is quite enough for comfortable tweening | ||
![image](https://user-images.githubusercontent.com/4208480/34684747-27532bc4-f4b7-11e7-9387-bc4e87ad0eab.png) | ||
1.5 KB is quite enough for full-featured and comfortable tweening | ||
![image](https://user-images.githubusercontent.com/4208480/34745457-a234e4b4-f5a1-11e7-8565-920006935cb4.png) | ||
@@ -9,2 +9,3 @@ ## Included features | ||
* Easing functions | ||
* Tweening delays | ||
* Chaining and groupping | ||
@@ -16,5 +17,5 @@ * Yo-yo effect | ||
* Ultra small size (only **<1.5KB** core, **<2KB** with all helpers, **<3KB** with all easings) | ||
* Low-leveled API lets you easily adapt it to your needs | ||
* Big list of ready-to-use easing functions. | ||
* Ultra small size (only **<1.5KB** core, **2KB** with all helpers, **<3KB** with all easings) | ||
* Low-level API lets you easily adapt it to your needs | ||
* Big list of ready-to-use easing functions | ||
* Easings and helpers are separated from core library so you can add only needed functions | ||
@@ -21,0 +22,0 @@ |
30519
1074
70