16.3. One-Second Motion
Copy,
Figure 16-7. One Second Motion
16.3.1. Goal Story
Bill is adding a new monthly bank order. The existing orders are shown in the usual wayas a table with one row per order, sorted by cost. Once he is
16.3.2. ProblemHow can you communicate that an element is shifting from one position to another? 16.3.3. Forces
16.3.4. Solution
Incrementally move an element from one location to another, or temporarily move it, to communicate that an event has occurred
. In most cases, the motion of the element involves a permanent change in its position. It can also be used to show a temporary displacement or gesture, such as a
There are several benefits of showing the motion explicitly:
The effect combines
Page Rearrangement
(Chapter 5) with
Scheduling
(Chapter 7). A loop runs for the duration of progresses, with each transition occurring perhaps once every 50
When an element has to move from point A to point B, in most cases it's logical for the trajectory to be the shortest distance from A to B, i.e., for the element to move as the crow flies. The algorithm in this case uses interpolationfor example, one-quarter of the time into the effect, an element will be one-quarter of the way between A and Bso, when moving from left to right, the left style of the element will be (0.25*x(A) + 0.75*x(B)), where x( ) represents the source and destinations' horizontal coordinate. This assumes a linear interpolation. You can also experiment with other algorithms, e.g., you might like to accelerate the element as it proceeds, which is often a more realistic model.
Note that you probably won't have to hand code motion, because libraries like Scriptaculous (discussed in the "Real-World Examples") are quite flexible and usually easy to
16.3.5. Decisions16.3.5.1. What events will trigger a motion effect?One-Second Motion is not very common (yet), but there are several potential applications. First, a permanent movement can show any of the following:
A temporary movement has its own applications:
Since motion can be distracting, you will likely want to limit its usage to the following situations:
Also consider whether you should use motion at all. The conventional wisdom is that motion is more natural as a transition because it's based on the physical world. But how about the massive population that grew up with computers and might be
16.3.5.2. What will the element do when it reaches its destination?
In every example I've seen, the element stops suddenly at its destination. However, it might appear more natural if the element reverberates when
16.3.6. Real-World Examples16.3.6.1. Scriptaculous libraryAs mentioned in One-Second Spotlight (see earlier in this chapter), Scriptaculous is a general-purpose JavaScript library. The visual effects demo (http://script.aculo.us/visual-effects) supports motion-based effects. 16.3.6.2. TiddlyWikiAs detailed in One-Second Mutation (see earlier in this chapter), clicking on a TiddlyWiki Microlink (Chapter 15; see http://tiddlywiki.com) causes the entire content to "leap out" from the link and form in a new position. 16.3.6.3. Backbase Portal
The Backbase Portal Demo (http://projects.backbase.com/RUI/portal.html) contains a page full of
Portlets
(Chapter 15) arranged in three
16.3.6.4. DHTML Lemmings
As detailed in
Sprite
(Chapter 15), DHTML Lemmings involves the movement of Lemming
16.3.6.5. MS-WindowsMS-Windows uses a form of One-Second Motion. When minimizing a window, the whole window appears to leap downward to its handle in the taskbar, like a large object being packed into a small container. The reverse process occurs upon activating the window. This is not an Ajax App, but is still significant, as it's frequently cited as a rationale for the kind of animation this pattern details. 16.3.7. Code Example: Scriptaculous Effects
Motion is one of the effects
The generic engine component controls the flow by continuously delegating to an individual effect object to perform an incremental animation. This is an example of the Strategy pattern (Gamma et al., 1995). The initialization sequence clears the frame count, computes the total effect time, and kicks off the loop:
start: function(options) {
...
this.currentFrame = 0;
this.startOn = new Date().getTime( );
this.finishOn = this.startOn + (this.options.duration*1000);
...
if(!this.options.sync) this.loop( );
}
The loop runs until the
loop: function( ) {
var timePos = new Date().getTime( );
if(timePos >= this.finishOn) {
this.render(1.0);
...
return;
}
var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
frame = Math.round(pos * this.options.fps *
this.options.duration);
if(frame > this.currentFrame) {
this.render(pos);
this.currentFrame = frame;
}
this.timeout = setTimeout(this.loop.bind(this), 10);
},
The main purpose of render( ) is to delegate to the effect strategy to perform the update. The strategy will receive a value between 0 and 1 to tell it how far the animation has proceeded.
The
MoveBy
effect takes a DOM element and tracks its start and end
initialize: function(element, toTop, toLeft) {
this.originalTop = parseFloat(this.element.style.top '0');
this.originalLeft = parseFloat(this.element.style.left '0');
this.toTop = toTop;
this.toLeft = toLeft;
Element.makePositioned(this.element);
...
}
Remember that the effects engine delegates to
update( )
for effect-specific behavior, passing in a progress ratio between 0 and 1. In the case of
MoveBy
, the algorithm
update: function(position) {
topd = this.toTop * position + this.originalTop;
leftd = this.toLeft * position + this.originalLeft;
this.setPosition(topd, leftd);
},
setPosition: function(topd, leftd) {
this.element.style.top = topd + "px";
this.element.style.left = leftd + "px";
}
The MoveBy effect in itself is useful for getting an object from A to B. But you can build on it to create effects such as motion displacements. One such effect, included in the Scriptaculous library, is Shake( ) , which swings an element left and right a few times. With the framework in place, the effect is easily defined as a sequence of moves:
Effect.Shake = function(element) {
return new Effect.MoveBy(element, 0, 20,
{ duration: 0.05, afterFinish: function(effect) {
new Effect.MoveBy(effect.element, 0, -40,
{ duration: 0.1, afterFinish: function(effect) {
new Effect.MoveBy(effect.element, 0, 40,
{ duration: 0.1, afterFinish: function(effect) {
...
}
16.3.8. Alternatives16.3.8.1. One-Second Spotlight and One-Second MutationOne-Second Spotlight and One-Second Mutation (see both earlier in this chapter) are also used to draw attention to a significant event. One-Second Motion is suited for indicating that an object's state has changed in the case where there is some geometric mapping to each object's state. When used as a temporary displacement effect, One-Second Motion is sometimes an alternative to these other patterns. 16.3.9. Related Patterns16.3.9.1. SpriteA Sprite (Chapter 15) often undergoes motion similar to One-Second Motion and can make use of similar interpolation calculations. 16.3.9.2. GuesstimateIn some cases, the motion is a form of Guesstimate (Chapter 13). When an object is moving around according to state information, the motion effect is effectively an estimate of what's happening between positions. 16.3.10. MetaphorUntil "Beam Me Up" teleportation technology hits the markets, every visible movement in the physical world is an illustration of this pattern. |