Part 3: The features of ‘$tween’
Our language will allow the creation of complex dom animation in an intuitive way. We are assuming that the user knows html and CSS, and basic dom selectors, but not javascript or jquery. It should be relatively easy to create interesting visual effects in an intuitive way. Designing for designers shapes the syntax of our language:
1. If function arguments have a unit, it should be obvious
2. There should be no functions where complex parameter arguments need to be remembered
3. When chaining together an animation, a designer should not have to remember specific order that they need to be chained together with
4. The design should leverage their current knowledge of the DOM, HTML and CSS
5. An animation should be built in the most intuitive way possible
Creating a basic animation:
An animation must consist of three basic things: 1) A attribute and how it should be modified, 2) A duration 3) A specific element to move
Because the designers know CSS, they should know the attribute they want to animate and how they want it modifed for example. There will be an advanced option to pass in a function that modifies a generic div. This creates a tween instance hereafter notifed as [tween]
$tween({“width”: “50px”}); // this will animate the object to eventually be 50px wide
$tween({“width”: “+50px”}); // this will animate the object to eventually be 50px larger than it was initially
$tween({“width”: “x2″}); // this will animate the object to eventually double it’s width
$tween(function(i /*between 0 and 1, essentially percentage done */){return {“width”: “” + i*50 + “px”}); // this will animate the object to eventually be 50px wide
A duration can be specified with
[tween].forSeconds(3) // this animation will take 3 seconds
[tween].forMilliseconds(3000) // this animation will take 3000 milliseconds
A tween can be attached to a specific element with
[tween].attach(“#a”) // attaches this element to the item #a
Finally a tween can be started with
[tween].go() // starts animation
[tween].go(“#a”) // attaches animation to #a and starts animations
Further, tweens can be modified in various ways
A tween can be repeated with
[tween].repeat(3) // animation will repeat 3 times
A tween can be eased with
[tween].ease(‘accelerate’) // start moving slowly and accelerate
[tween].ease(‘decelerate’) // start moving fast and slow down
Two or more tweens can occur simultaneously, in parallel with
$tween.parallel(tween1, tween2, . . . .) // all tweens start at same time
Two or more tween can occur consecutively, serialized with
$tween.serial(tween1, tween2, tween3) // all tweens happen consecutively
A pause can be created with
$tween.pauseForSeconds(2); // does nothing for two seconds
$tween.pauseForMilliseconds(2000); // does nothing for 2 seconds
Complicated animations can be build from simpler animations, all which are abstracted to the animation level. In a rich, interactive environment, most objects will have some sort of roll-over effect and many will share similar roll-over effects, this will make managing and creating these effects easy.
Part 4: Implementation
An animation will essentially be a tree that knows how to invoke it’s children
Every different action listen above will be a different node type. It will set the node that it was called from as the child. For example tween1.attach(div) creates an ‘attachment node’ that has tween1 as a child. $tween.and(tween1, tween2) will create an ‘and node’ that has both tween1 and tween2 as it’s children.
Each object will have a trigger(params) function and an animate(i, params). The params object is used to pass information on to a nodes children. ‘i’ is used to represent how far along an animation is between 0.0 and 1.0.
Calling go() on a tween instance will call that nodes trigger() method
A call on trigger() or animate(i) on a specific node does one of
1) modifies params and calls the node’s child
2) branches the single trigger() or animate() call to multiple trigger() or animate() calls
3) modifies the i parameter
Here we explain how each node is used and created and how they do one of the above 3 actions:
BASIC NODES:
Tween.attr: created using $tween({attr: value});
This is pretty much the basic animator, it only knows a single CSS
attribute and either a modifier or a final value. An identity node
exists too that simply returns true always. Because it is the basic
animator it is less flexible.
trigger() – trigger cannot be called on this node since it doesn’t
have a duration or a dom element.
animate(i, div = null) – i always represents a
value between 0 and 1 that is how far along this single animation
should be. div must be a single dom element. Animate modifies an
elements css attributes based on the inital value that it looks up,
the final modification necessary and the percentage of this that
should be done.
Tween.duration: created using [tween].forSeconds(value)
This is what converts a trigger() call into an animate() call and
therefore creates a percentage based context for it’s child.
trigger(params) – first calls it’s child with animate(0, div?) – if
there is a div parameter in params it is passed on to the animate
call. If params has a callback parameter then this is called after
the animation is done (to deal with ‘then’s). If params has an ease
parameter than this is used to modify i before it’s passed down (a
linear ease could be modified to parabolic)
animate(i) – an error should be thrown in this case. this means that
two intervals have been set which doesn’t have an inuitive meaning.
Tween.attach: created using [tween].attach(value . . . )
This is what is responsible for attaching an animation to a DOM
selector. The value passed in on instantiation may represent many
elements, this breaks that up into multiple animations
trigger(params) – Calls trigger(params) on it’s child setting the div
parameter to every DOM item that is selected using ‘value’. If there
is already a div parameter in params it throws an error
animate(i) – Calls animate(i, div) where div is every unique DOM item
that was selected using ‘value’. If called with two arguments, throws
and error
——
ACCESSORY NODES:
Tween.and: created using $tween.and(value, value . . .)
This is doing two animations at the same time
trigger(params) – Calls trigger(params)on both it’s children.
animate(i, params) – Calls animate(i, params) on both it’s children
Tween.then: created using $tween.then(value, value . . .)
This is doing one animation and then another
trigger(params) – Calls trigger(params) on first child, setting a
callback param that is a function that calls trigger(params) onto
second animation etc. If params already has a callback parameter then
this callback should be called first, and then the second parameter.
animate(i, params) – If this is called it means that the children do
not have durations and just assumes that they all get equal parts of
the animation. If n = the amount of values passed in, then just calls
first child’s animate(i, params) on the first child for values of i <
1/n, calls animate(i, params) on the second child if 1/n < i < 2/n etc
Tween.repeat: created using [tween].repeat(value)
This simply does the same as [tween].then except the callback
Tween.pause(value): created using $tween.pauseForSeconds(value)
essentially creates an tween that does nothing for 'value' seconds
return $tween().forSeconds(value);
Tween.ease(value): created using [tween].ease(value)
This adds an easing capability to tweens. It will have preset values
that can be passed in such as 'gravity' or 'slide'. It should know
how to convert a 'linear' value between 0 and 1 to an eased value
trigger(params) – adds a function that knows how to modify i to the
ease paramater of params. If 'ease' already exists throws error.
animate(i, params) – simply modifies i to the new value and calls child.