@tweenjs/tween.js
Advanced tools
Comparing version 16.8.0 to 16.9.0
{ | ||
"name": "@tweenjs/tween.js", | ||
"description": "Super simple, fast and easy to use tweening engine which incorporates optimised Robert Penner's equations.", | ||
"version": "16.8.0", | ||
"version": "16.9.0", | ||
"main": "src/Tween.js", | ||
@@ -29,7 +29,7 @@ "homepage": "https://github.com/tweenjs/tween.js", | ||
"devDependencies": { | ||
"jscs": "^2.2.0", | ||
"jshint": "^2.8.0", | ||
"nodeunit": "^0.9.1", | ||
"jscs": "^2.11.0", | ||
"jshint": "^2.9.4", | ||
"nodeunit": "^0.9.5", | ||
"semantic-release": "^6.3.2" | ||
} | ||
} |
@@ -12,18 +12,28 @@ # tween.js | ||
```javascript | ||
var coords = { x: 0, y: 0 }; | ||
var tween = new TWEEN.Tween(coords) | ||
.to({ x: 100, y: 100 }, 1000) | ||
.onUpdate(function() { | ||
console.log(this.x, this.y); | ||
}) | ||
.start(); | ||
var box = document.createElement('div'); | ||
box.style.setProperty('background-color', '#008800'); | ||
box.style.setProperty('width', '100px'); | ||
box.style.setProperty('height', '100px'); | ||
document.body.appendChild(box); | ||
// Setup the animation loop. | ||
function animate(time) { | ||
requestAnimationFrame(animate); | ||
TWEEN.update(time); | ||
} | ||
requestAnimationFrame(animate); | ||
function animate(time) { | ||
requestAnimationFrame(animate); | ||
TWEEN.update(time); | ||
} | ||
var coords = { x: 0, y: 0 }; // Start at (0, 0) | ||
var tween = new TWEEN.Tween(coords) // Create a new tween that modifies 'coords'. | ||
.to({ x: 300, y: 200 }, 1000) // Move to (300, 200) in 1 second. | ||
.easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth. | ||
.onUpdate(function() { // Called after tween.js updates 'coords'. | ||
// Move 'box' to the position described by 'coords' with a CSS translation. | ||
box.style.setProperty('transform', 'translate(' + coords.x + 'px, ' + coords.y + 'px)'); | ||
}) | ||
.start(); // Start the tween immediately. | ||
``` | ||
[Test it with CodePen](https://codepen.io/mikebolt/pen/zzzvZg) | ||
## Installation | ||
@@ -100,2 +110,3 @@ | ||
* Also: [libtween](https://github.com/jsm174/libtween), a port of tween.js to C by [jsm174](https://github.com/jsm174) | ||
* Also: [es6-tween](https://github.com/tweenjs/es6-tween), a port of tween.js to ES6/Harmony by [dalisoft](https://github.com/dalisoft) | ||
@@ -275,3 +286,3 @@ ## Examples | ||
[npm-image]: https://img.shields.io/npm/v/tween.js.svg | ||
[npm-image]: https://img.shields.io/npm/v/@tweenjs/tween.js.svg | ||
[npm-url]: https://npmjs.org/package/@tweenjs/tween.js | ||
@@ -286,1 +297,2 @@ [downloads-image]: https://img.shields.io/npm/dm/@tweenjs/tween.js.svg | ||
[cdnjs-url]: https://cdnjs.com/libraries/tween.js | ||
384
src/Tween.js
@@ -10,64 +10,86 @@ /** | ||
var TWEEN = TWEEN || (function () { | ||
var TWEEN = TWEEN || {}; | ||
var _tweens = []; | ||
return { | ||
TWEEN._nextId = 0; | ||
TWEEN.nextId = function () { | ||
return TWEEN._nextId++; | ||
}; | ||
getAll: function () { | ||
return _tweens; | ||
TWEEN.Group = function () { | ||
this._tweens = {}; | ||
this._tweensAddedDuringUpdate = {}; | ||
}; | ||
}, | ||
TWEEN.Group.prototype = assign(Object.create(Object.prototype), { | ||
getAll: function () { | ||
removeAll: function () { | ||
return Object.keys(this._tweens).map(function (tweenId) { | ||
return this._tweens[tweenId]; | ||
}.bind(this)); | ||
_tweens = []; | ||
}, | ||
}, | ||
removeAll: function () { | ||
add: function (tween) { | ||
this._tweens = {}; | ||
_tweens.push(tween); | ||
}, | ||
}, | ||
add: function (tween) { | ||
remove: function (tween) { | ||
this._tweens[tween.getId()] = tween; | ||
this._tweensAddedDuringUpdate[tween.getId()] = tween; | ||
var i = _tweens.indexOf(tween); | ||
}, | ||
if (i !== -1) { | ||
_tweens.splice(i, 1); | ||
} | ||
remove: function (tween) { | ||
}, | ||
delete this._tweens[tween.getId()]; | ||
delete this._tweensAddedDuringUpdate[tween.getId()]; | ||
update: function (time, preserve) { | ||
}, | ||
if (_tweens.length === 0) { | ||
return false; | ||
} | ||
update: function (time, preserve) { | ||
var i = 0; | ||
var tweenIds = Object.keys(this._tweens); | ||
time = time !== undefined ? time : TWEEN.now(); | ||
if (tweenIds.length === 0) { | ||
return false; | ||
} | ||
while (i < _tweens.length) { | ||
time = time !== undefined ? time : TWEEN.now(); | ||
if (_tweens[i].update(time) || preserve) { | ||
i++; | ||
} else { | ||
_tweens.splice(i, 1); | ||
// Tweens are updated in "batches". If you add a new tween during an update, then the | ||
// new tween will be updated in the next batch. | ||
// If you remove a tween during an update, it will normally still be updated. However, | ||
// if the removed tween was added during the current batch, then it will not be updated. | ||
while (tweenIds.length > 0) { | ||
this._tweensAddedDuringUpdate = {}; | ||
for (var i = 0; i < tweenIds.length; i++) { | ||
if (this._tweens[tweenIds[i]].update(time) === false) { | ||
this._tweens[tweenIds[i]]._isPlaying = false; | ||
if (!preserve) { | ||
delete this._tweens[tweenIds[i]]; | ||
} | ||
} | ||
} | ||
return true; | ||
tweenIds = Object.keys(this._tweensAddedDuringUpdate); | ||
} | ||
}; | ||
})(); | ||
return true; | ||
} | ||
}); | ||
// Create global group | ||
assignDeep(TWEEN, new TWEEN.Group()); | ||
// Include a performance.now polyfill. | ||
@@ -103,31 +125,71 @@ // In node.js, use process.hrtime. | ||
TWEEN.Tween = function (object) { | ||
function assign(target, source) { | ||
var keys = Object.keys(source); | ||
var length = keys.length; | ||
var _object = object; | ||
var _valuesStart = {}; | ||
var _valuesEnd = {}; | ||
var _valuesStartRepeat = {}; | ||
var _duration = 1000; | ||
var _repeat = 0; | ||
var _repeatDelayTime; | ||
var _yoyo = false; | ||
var _isPlaying = false; | ||
var _reversed = false; | ||
var _delayTime = 0; | ||
var _startTime = null; | ||
var _easingFunction = TWEEN.Easing.Linear.None; | ||
var _interpolationFunction = TWEEN.Interpolation.Linear; | ||
var _chainedTweens = []; | ||
var _onStartCallback = null; | ||
var _onStartCallbackFired = false; | ||
var _onUpdateCallback = null; | ||
var _onCompleteCallback = null; | ||
var _onStopCallback = null; | ||
for (var i = 0; i < length; i += 1) { | ||
target[keys[i]] = source[keys[i]]; | ||
} | ||
this.to = function (properties, duration) { | ||
return target; | ||
} | ||
_valuesEnd = properties; | ||
function assignDeep(target, source) { | ||
// Assign own properties | ||
assign(target, source); | ||
// Assign prototype properties | ||
var targetProto = Object.getPrototypeOf(target); | ||
var sourceProto = Object.getPrototypeOf(source); | ||
for (var prop in sourceProto) { | ||
targetProto[prop] = sourceProto[prop]; | ||
} | ||
return target; | ||
} | ||
TWEEN.Tween = function (object, group) { | ||
this._object = object; | ||
this._valuesStart = {}; | ||
this._valuesEnd = {}; | ||
this._valuesStartRepeat = {}; | ||
this._duration = 1000; | ||
this._repeat = 0; | ||
this._repeatDelayTime = undefined; | ||
this._yoyo = false; | ||
this._isPlaying = false; | ||
this._reversed = false; | ||
this._delayTime = 0; | ||
this._startTime = null; | ||
this._easingFunction = TWEEN.Easing.Linear.None; | ||
this._interpolationFunction = TWEEN.Interpolation.Linear; | ||
this._chainedTweens = []; | ||
this._onStartCallback = null; | ||
this._onStartCallbackFired = false; | ||
this._onUpdateCallback = null; | ||
this._onCompleteCallback = null; | ||
this._onStopCallback = null; | ||
this._group = group || TWEEN; | ||
this._id = TWEEN.nextId(); | ||
}; | ||
TWEEN.Tween.prototype = assign(Object.create(Object.prototype), { | ||
getId: function getId() { | ||
return this._id; | ||
}, | ||
isPlaying: function isPlaying() { | ||
return this._isPlaying; | ||
}, | ||
to: function to(properties, duration) { | ||
this._valuesEnd = properties; | ||
if (duration !== undefined) { | ||
_duration = duration; | ||
this._duration = duration; | ||
} | ||
@@ -137,21 +199,21 @@ | ||
}; | ||
}, | ||
this.start = function (time) { | ||
start: function start(time) { | ||
TWEEN.add(this); | ||
this._group.add(this); | ||
_isPlaying = true; | ||
this._isPlaying = true; | ||
_onStartCallbackFired = false; | ||
this._onStartCallbackFired = false; | ||
_startTime = time !== undefined ? time : TWEEN.now(); | ||
_startTime += _delayTime; | ||
this._startTime = time !== undefined ? time : TWEEN.now(); | ||
this._startTime += this._delayTime; | ||
for (var property in _valuesEnd) { | ||
for (var property in this._valuesEnd) { | ||
// Check if an Array was provided as property value | ||
if (_valuesEnd[property] instanceof Array) { | ||
if (this._valuesEnd[property] instanceof Array) { | ||
if (_valuesEnd[property].length === 0) { | ||
if (this._valuesEnd[property].length === 0) { | ||
continue; | ||
@@ -161,3 +223,3 @@ } | ||
// Create a local copy of the Array with the start value at the front | ||
_valuesEnd[property] = [_object[property]].concat(_valuesEnd[property]); | ||
this._valuesEnd[property] = [this._object[property]].concat(this._valuesEnd[property]); | ||
@@ -168,3 +230,3 @@ } | ||
// we should not set that property in the object | ||
if (_object[property] === undefined) { | ||
if (this._object[property] === undefined) { | ||
continue; | ||
@@ -174,9 +236,9 @@ } | ||
// Save the starting value. | ||
_valuesStart[property] = _object[property]; | ||
this._valuesStart[property] = this._object[property]; | ||
if ((_valuesStart[property] instanceof Array) === false) { | ||
_valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings | ||
if ((this._valuesStart[property] instanceof Array) === false) { | ||
this._valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings | ||
} | ||
_valuesStartRepeat[property] = _valuesStart[property] || 0; | ||
this._valuesStartRepeat[property] = this._valuesStart[property] || 0; | ||
@@ -187,15 +249,15 @@ } | ||
}; | ||
}, | ||
this.stop = function () { | ||
stop: function stop() { | ||
if (!_isPlaying) { | ||
if (!this._isPlaying) { | ||
return this; | ||
} | ||
TWEEN.remove(this); | ||
_isPlaying = false; | ||
this._group.remove(this); | ||
this._isPlaying = false; | ||
if (_onStopCallback !== null) { | ||
_onStopCallback.call(_object, _object); | ||
if (this._onStopCallback !== null) { | ||
this._onStopCallback.call(this._object, this._object); | ||
} | ||
@@ -206,98 +268,97 @@ | ||
}; | ||
}, | ||
this.end = function () { | ||
end: function end() { | ||
this.update(_startTime + _duration); | ||
this.update(this._startTime + this._duration); | ||
return this; | ||
}; | ||
}, | ||
this.stopChainedTweens = function () { | ||
stopChainedTweens: function stopChainedTweens() { | ||
for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) { | ||
_chainedTweens[i].stop(); | ||
for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) { | ||
this._chainedTweens[i].stop(); | ||
} | ||
}; | ||
}, | ||
this.delay = function (amount) { | ||
delay: function delay(amount) { | ||
_delayTime = amount; | ||
this._delayTime = amount; | ||
return this; | ||
}; | ||
}, | ||
this.repeat = function (times) { | ||
repeat: function repeat(times) { | ||
_repeat = times; | ||
this._repeat = times; | ||
return this; | ||
}; | ||
}, | ||
this.repeatDelay = function (amount) { | ||
repeatDelay: function repeatDelay(amount) { | ||
_repeatDelayTime = amount; | ||
this._repeatDelayTime = amount; | ||
return this; | ||
}; | ||
}, | ||
this.yoyo = function (yoyo) { | ||
yoyo: function yoyo(yoyo) { | ||
_yoyo = yoyo; | ||
this._yoyo = yoyo; | ||
return this; | ||
}; | ||
}, | ||
easing: function easing(easing) { | ||
this.easing = function (easing) { | ||
_easingFunction = easing; | ||
this._easingFunction = easing; | ||
return this; | ||
}; | ||
}, | ||
this.interpolation = function (interpolation) { | ||
interpolation: function interpolation(interpolation) { | ||
_interpolationFunction = interpolation; | ||
this._interpolationFunction = interpolation; | ||
return this; | ||
}; | ||
}, | ||
this.chain = function () { | ||
chain: function chain() { | ||
_chainedTweens = arguments; | ||
this._chainedTweens = arguments; | ||
return this; | ||
}; | ||
}, | ||
this.onStart = function (callback) { | ||
onStart: function onStart(callback) { | ||
_onStartCallback = callback; | ||
this._onStartCallback = callback; | ||
return this; | ||
}; | ||
}, | ||
this.onUpdate = function (callback) { | ||
onUpdate: function onUpdate(callback) { | ||
_onUpdateCallback = callback; | ||
this._onUpdateCallback = callback; | ||
return this; | ||
}; | ||
}, | ||
this.onComplete = function (callback) { | ||
onComplete: function onComplete(callback) { | ||
_onCompleteCallback = callback; | ||
this._onCompleteCallback = callback; | ||
return this; | ||
}; | ||
}, | ||
this.onStop = function (callback) { | ||
onStop: function onStop(callback) { | ||
_onStopCallback = callback; | ||
this._onStopCallback = callback; | ||
return this; | ||
}; | ||
}, | ||
this.update = function (time) { | ||
update: function update(time) { | ||
@@ -308,33 +369,33 @@ var property; | ||
if (time < _startTime) { | ||
if (time < this._startTime) { | ||
return true; | ||
} | ||
if (_onStartCallbackFired === false) { | ||
if (this._onStartCallbackFired === false) { | ||
if (_onStartCallback !== null) { | ||
_onStartCallback.call(_object, _object); | ||
if (this._onStartCallback !== null) { | ||
this._onStartCallback.call(this._object, this._object); | ||
} | ||
_onStartCallbackFired = true; | ||
this._onStartCallbackFired = true; | ||
} | ||
elapsed = (time - _startTime) / _duration; | ||
elapsed = (time - this._startTime) / this._duration; | ||
elapsed = elapsed > 1 ? 1 : elapsed; | ||
value = _easingFunction(elapsed); | ||
value = this._easingFunction(elapsed); | ||
for (property in _valuesEnd) { | ||
for (property in this._valuesEnd) { | ||
// Don't update properties that do not exist in the source object | ||
if (_valuesStart[property] === undefined) { | ||
if (this._valuesStart[property] === undefined) { | ||
continue; | ||
} | ||
var start = _valuesStart[property] || 0; | ||
var end = _valuesEnd[property]; | ||
var start = this._valuesStart[property] || 0; | ||
var end = this._valuesEnd[property]; | ||
if (end instanceof Array) { | ||
_object[property] = _interpolationFunction(end, value); | ||
this._object[property] = this._interpolationFunction(end, value); | ||
@@ -355,3 +416,3 @@ } else { | ||
if (typeof (end) === 'number') { | ||
_object[property] = start + (end - start) * value; | ||
this._object[property] = start + (end - start) * value; | ||
} | ||
@@ -363,4 +424,4 @@ | ||
if (_onUpdateCallback !== null) { | ||
_onUpdateCallback.call(_object, value); | ||
if (this._onUpdateCallback !== null) { | ||
this._onUpdateCallback.call(this._object, value); | ||
} | ||
@@ -370,34 +431,34 @@ | ||
if (_repeat > 0) { | ||
if (this._repeat > 0) { | ||
if (isFinite(_repeat)) { | ||
_repeat--; | ||
if (isFinite(this._repeat)) { | ||
this._repeat--; | ||
} | ||
// Reassign starting values, restart by making startTime = now | ||
for (property in _valuesStartRepeat) { | ||
for (property in this._valuesStartRepeat) { | ||
if (typeof (_valuesEnd[property]) === 'string') { | ||
_valuesStartRepeat[property] = _valuesStartRepeat[property] + parseFloat(_valuesEnd[property]); | ||
if (typeof (this._valuesEnd[property]) === 'string') { | ||
this._valuesStartRepeat[property] = this._valuesStartRepeat[property] + parseFloat(this._valuesEnd[property]); | ||
} | ||
if (_yoyo) { | ||
var tmp = _valuesStartRepeat[property]; | ||
if (this._yoyo) { | ||
var tmp = this._valuesStartRepeat[property]; | ||
_valuesStartRepeat[property] = _valuesEnd[property]; | ||
_valuesEnd[property] = tmp; | ||
this._valuesStartRepeat[property] = this._valuesEnd[property]; | ||
this._valuesEnd[property] = tmp; | ||
} | ||
_valuesStart[property] = _valuesStartRepeat[property]; | ||
this._valuesStart[property] = this._valuesStartRepeat[property]; | ||
} | ||
if (_yoyo) { | ||
_reversed = !_reversed; | ||
if (this._yoyo) { | ||
this._reversed = !this._reversed; | ||
} | ||
if (_repeatDelayTime !== undefined) { | ||
_startTime = time + _repeatDelayTime; | ||
if (this._repeatDelayTime !== undefined) { | ||
this._startTime = time + this._repeatDelayTime; | ||
} else { | ||
_startTime = time + _delayTime; | ||
this._startTime = time + this._delayTime; | ||
} | ||
@@ -409,11 +470,11 @@ | ||
if (_onCompleteCallback !== null) { | ||
if (this._onCompleteCallback !== null) { | ||
_onCompleteCallback.call(_object, _object); | ||
this._onCompleteCallback.call(this._object, this._object); | ||
} | ||
for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) { | ||
for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i++) { | ||
// Make the chained tweens start exactly at the time they should, | ||
// even if the `update()` method was called way past the duration of the tween | ||
_chainedTweens[i].start(_startTime + _duration); | ||
this._chainedTweens[i].start(this._startTime + this._duration); | ||
} | ||
@@ -429,7 +490,6 @@ | ||
}; | ||
} | ||
}); | ||
}; | ||
TWEEN.Easing = { | ||
@@ -436,0 +496,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
31727
593
295