-
Notifications
You must be signed in to change notification settings - Fork 2
Version 2 plans #1
Comments
I like that idea. By the way, since we're on the topic of a new version, how do you feel about Famous 0.3 Transitionable pattern? Example here: http://deprecated.famous.org/university/lessons/#/famous-102/transitionables/1 The idea would be something like (slightly modified from the Famous example, renamed to Tween): import sleep from 'awaitbox/timers/sleep'
import Tween from 'tween.js/Tween' // v2
async function app() {
let tween = new Tween(0) // starting value
tween.to(100, {duration: 2000, curve: 'ExpoIn'})
// start tween
requestAnimationFrame(function loop(time) {
console.log(tween.get(time))
if (tween.isRunning) requestAnimationFrame(loop)
})
// delay for a sec
await sleep(1000)
tween.pause() // causes current animation loop to stop.
// delay for another sec
await sleep(1000)
// start new loop to unpause.
requestAnimationFrame(function loop(time) {
console.log(tween.get(time))
if (tween.isRunning) requestAnimationFrame(loop)
})
await sleep(500)
tween.stop() // stop a half second early.
}
app() Maybe the
States (assume the conditional expressions are truthy):
In all cases, the following two booleans are composed:
The paused state can only be true if the Transitionable was started already, otherwise Custom easing functions can be supplied: rotationTransition.to(100, {duration: 1000, curve: customFunction}) So far, that covers the Tween class and custom functions (what should the signature for custom tween functions be?) As for a tween manager, maybe that part isn't necessary. Seems like it is difficult to guess people's use cases. For example, in v1, If a tween manager class is made, maybe components would instantiate instances of it, so updating it simply calls the import sleep from 'awaitbox/timers/sleep'
import TweenManager from 'tween.js/TweenManager' // v2
import {tween1, tween2, tween3, tween4} from 'somewhere'
async function app() {
// pass tweens into constructor.
let tweens = new TweenManager([ tween1, tween2, tween3 ])
// inside an animation loop...
requestAnimationFrame(function loop() {
// updates only tweens that are started and not paused and not complete.
tweens.update(time)
console.log(tween1.value)
console.log(tween2.value)
console.log(tween3.value)
console.log(tween4.value)
// if any of them managed tweens are running.
if (tweens.hasRunning) requestAnimationFrame(loop)
})
await sleep(1000)
// pass to add method later.
tweens.add(tween4)
await sleep(1000)
// ability to remove them
tweens.remove(tween3)
}
app() TweenManager might have booleans too:
|
import Tween from './tweenjs/src/core.js';
import Easing from './tweenjs/dist/easing.js';
import GroupTween from './tweenjs/dist/group.js';
import SleepWake from './tweenjs/dist/powersaver.js';
import Interpolation from './tweenjs/dist/interpolation.js';
let tween1 = Tween.get({x:50,y:50}).duration('2s').end({x:0,y:100});
let tween2 = Tween.get({z:5,a:0}).duration('1.8s').end({z:3,a:0.5});
let tweenGroup = new GroupTween();
tweenGroup.add(tween1).add(tween2).set({tween2:{Interpolation:Interpolation.Bezier}});
tweenGroup.start();
SleepWake.change(function(status){
if (status === 'wake') {
tweenGroup.wake();
} else {
tweenGroup.sleep(); // power saving mode to save battery, especially on mobile device
}
}); @sole, Do you like syntax i writed.
|
Enthusiasm – YES! Want to jump on board – YES! |
I really like the modularity idea and I think that we need to move in that direction. However, maybe we don't need a separate repository for each module? It might help keep issues separate, but as long as the modules are all single .js files, I think keeping them in a single repository is a good option. @trusktr I'm not sure that I understand the Transitionable pattern. In your example, you tween a single value. I hope that tweening multiple values of an object simultaneously will still be possible; I think that is one of the strongest features of tween.js.
When I created a prototype of the TweenGroup class (twice) I realized that my class was basically a flexible version of the TWEEN object. If we made a TweenManager class it would basically be the exact same as the TweenGroup class that we have proposed before, and visa versa. I like the idea of making the tween's state inspectable. In my mind there are two different kinds of "pause":
I think that both kinds of pausing should be supported, but we should at least make it clear how "pause" actually behaves. |
I think you're can look at here about ES6 class(ed) Tween.js |
@dalisoft I don't think this idea belongs in Tween.js. We can just start and stop a Tween or TweenManager (or
@mikebolt The Famous let tween = new Tween(0) // starting value
tween.to(100, {duration: 2000, curve: 'ExpoIn'})
// ... time passes ...
console.log(tween.get(time)) // n or let tween = new Tween([0, 10, 5]) // multiple starting values
tween.to([100, 0, 20], {duration: 2000, curve: 'ExpoIn'})
// ... time passes ...
console.log(tween.get(time)) // [n1, n2, n3] We could also support an additional object form (Famous Transitionable doesn't) similar to Tween.js v1: let tween = new Tween({x:0, y:10, z:5}) // multiple starting values
tween.to({x:100, y:0, z:20}, {duration: 2000, curve: 'ExpoIn'})
// ... time passes ...
console.log(tween.get(time)) // {x:n1, y:n2, z:n3} The third form would has the same advantage as Maybe
Yep, almost the same concept, except that we add Tweens and remove Tweens from separate instances rather than a single global instance. This is a great idea so that components don't hammer each other. Imagine installing a bunch of animated components from NPM and they all unintentionally updating each other's Tweens and causing unexpected behavior. So the examples would be: let tween = new Tween(0)
tween.to(100, {duration: 2000, curve: 'ExpoIn'})
// ... time passes ...
console.log(tween.next(time))
When would you want to use the second behavior? |
(or: why sole is afraid of getting too close to the current code)
The first release of this library was sometime around 2010. This is ancient in JS terms! So much has changed, so many people have participated on it. It's used by many but maintained by few. This has to change.
The amount of bugs and issues is way more than I can deal with, and one of the big reasons for that is that I do not understand all the code that I didn't write. There are missing tests, and the interactions between some features are... quite unexpected sometimes.
Also, the way things are done on the web is different now. We have node.js modules and build processses, we have ES6 and better JavaScript, we have getters and setters (which tween does not support for some reason), there are CSS animations, etc etc... People often just want to use the easing equations, but they have to include the whole library. Etc.
There were talks for a "es6" version of the library but it never took off for various reasons (here's a repo for it).
As it stands right now, I don't think an ES6 version is attractive per se - the tooling around ES6 to ES5 is quite volatile, and I can't find immediate useful advantages of rewriting in ES6, but what would be really interesting is to start a V2 that is built out of other modules. Each module should be a different project and github repository, published to npm individually. Then "Tween-v2" should be built by requiring those modules.
An structure could be this:
I believe this would be a good compromise between trying to adding new stuff into the existing single
src/Tween.js
file, which is getting really unwieldly, and rewriting everything with a new syntax and having to add lots of slow build steps to eventually end up transpiling into ES5 because no browser implements ES6 modules yet.Another advantage is that we would enter this mindset of splitting things in modules and get used to building Tween or importing parts of it Tween just as we need them, instead of piling all into The Code Monolith. For example, we could have a project that simplifies animating CSS properties by adding 'px' etc (which the current version doesn't). This would not be used by everyone, hence it would live on a different repository.
It makes it easier for people who want to contribute with new features, as maintainers do not need to be super worried that a new addition is going to break the core functionality.
I am inclined to think that we do not need a new "future" tween.js project repository. We could probably start prototyping this new version in a new branch and publish to npm with a 'next' kind of tag if people want to play with it. The most important stuff would be actually in other modules anyway. When we consider the new version solid enough we can merge it back to master, and if someone needs an old version for compatibility, there will always be an archive.
Thoughts? Enthusiasm? Who wants to jump on board? Everyone welcome! 🙋🏻
The text was updated successfully, but these errors were encountered: