Section 15.2. Sprite


15.2. Sprite

Bitmap, Buffer, Character, Layer, Overlay, Shape, Sprite, Z-Index

Figure 15-2. Sprite


15.2.1. Goal Story

Not for the first time, Pam is negotiating to eliminate a stack of requirements from the project goals. Having successfully convinced the client that "Security Features" was never really worthwhile, she drags a "Magic Eraser" Sprite from the Tool Palette to the "Security Features" requirement, jiggles the mouse a couple of times, and the eraser is animated for a second as the requirement fades away.

15.2.2. Problem

How can you ensure that visual content is flexible?

15.2.3. Forces

  • Rich visual displays are often the most effective way to present information.

  • Information frequently changes as the user interacts with and new data is received from the server; hence, the visual display needs to update frequently.

  • It's expensive to continuously download new visual content.

15.2.4. Solution

Augment the display with Spritesi.e., small, flexible, icon-like blocks of content. Typically, the Sprites are images, but they may also be div elements containing text or images or a combination of both. The name refers to the Sprites used in traditional graphics programming, particularly gaminthose little graphics representing players, enemies, and other objects capable of moving around a scene and animating themselves to reflect current activity. The entire scene does not need to be recomputed each time, only the Sprites. DOM elements are not (yet) capable of more advanced features such as arbitrary rotation, but many aspects of Sprites can actually be translated to a web context.

Google Maps is a case in point. If you search for "museum new york," a set of thumbtack Sprites will appear on the map, one for each museum. Then, if you click on a thumbtack, a new speech balloon Sprite will show up with the precise address. Using Sprites, Google spares itself the burden of preparing images for every possible configuration, and from generating images on the fly. All it needs to do is ensure that there's a basic display of the map in question, then overlay the thumbtacks and speech balloons.

Sprites are often implemented as div elements or simply as images. They usually appear "in front of" the rest of the document and are sometimes partially transparent. Following are the relevant CSS properties (also see Page Rearrangement [Chapter 5]):


zIndex

Determines how elements are stacked. Sprites usually have a high value in order to appear in front of other elements.


left, right, top, and bottom

Often used to position a Sprite. position can also be set to influence how the browser interprets these settings.


opacity

Often used to make the Sprite partially transparent. (IE requires the alpha filter workaround; see http://www.domedia.org/oveklykken/css-transparency.php.)


backgroundImage

Used to select a background image when the Sprite is a div. As long as there is no foreground content, the background image is shown. The image doesn't need to be rectangular because a transparent GIF file can be used to show any arbitrary shape.

You can also animate the Sprite by rapidly changing its appearance. Unfortunately, JavaScript cannot easily control animated GIFs, so that's not a viable option. However, animation is easy enough with some Scheduling (Chapter 7). One simple technique is to set up a recurring changeImage( ) action, in which the element's backgroundImage is continuously run through a cycle of different images. Ideally, you should preload the images to avoid a slow cycle the first time round. Several tricks are available for preloading, the most common being set an invisible image's source to point to the new image. An alternative animation technique is outlined in the section "Code Example: DHTML Lemmings," later in this chapter.

15.2.5. Decisions

15.2.5.1. What file format will the Sprite image be?

Sprites are usually images, but what file format should you useJPEG, GIF, or PNG? There are several considerations:

  • Portability

  • Image quality

  • File size

  • Transparency

JPEG may be the most common format on the Web, but it is ruled out for most Sprites. It doesn't support transparent pixels, so the Sprite must be rectangular, and it is not actually very effective at storing the kinds of images typically used for Sprites: small, cartoonish line drawings. So JPEG is only a consideration in the rare case that you have a fairly large, rectangular, photo-like Sprite.

This leaves GIF and PNG as the most common choices. An intellectual property cloud used to hang over GIF, but the patent expired in 2003 (http://en.wikipedia.org/wiki/Gif), so it's no longer a valid reason to avoid GIF. PNG does have some technical advantages over GIF, particularly variable transparency, but unfortunately that has not been correctly implemented in IE6 and earlier. So to support older IE editions, you'll need to manipulate opacity if you want to achieve transparency, regardless of the format. Also, even older versions of IE don't support PNG at all (http://www.libpng.org/pub/png/pngapbr.html).

In summary, GIF should be the default choice; only use JPEG or PNG if there is a specific reason for doing so.

15.2.5.2. Will the Sprite be animated?

Ongoing animation can be distracting, but a quick animation is an effective way to convey what's happening. Consider how the "one-second" visual effects might be used:

  • One-Second Spotlight (Chapter 16): You might Materialise a Sprite when it first appears or Fade In the Sprite when it's subject to an action.

  • One-Second Mutation (Chapter 16): You might Form a Sprite when it first appears, or rapidly Metamorphise it in a cycle in order to provide the illusion of continuous change.

15.2.6. Real-World Examples

15.2.6.1. DHTML Lemmings

DHTML Lemmings (http://www.oldgames.dk/freeflashgames/arcadegames/playlemmings.php) by Tino Zijdel ("Crisp") is a game that uses Sprites in their traditional gaming sense. Lemmings are shown performing different actions, and the characters change shape as they move around the game space. The entire thing is orchestrated with DOM and CSS scripting.

15.2.6.2. Google Maps

As discussed earlier in the Solution, Google Maps (http://maps.google.com) overlays the basic map with thumbtacks to highlight certain locations. As an interesting variant, look at how thumbtacks are used by Housing Maps (http://housingmaps.com/), the Maps-Craigslist mashup overviewed in Cross-Domain Proxy (Chapter 10).

15.2.6.3. Quek

Quek (http://www.quek.nl) is a fun use of Sprites as chat avatars (Figure 15-3). The application is a "chat-and-surf" program, meaning that Quek users can chat about a web site they're visiting at the same time. Traditionally, such applications have involved Richer Plugins (Chapter 8), but Quek avoids any of that. It works by rendering the entire target web site, so you're always actually on a Quek page, but the page looks the same as the target site. Each user that logs into Quek is assigned a unique Sprite consisting of an image, a text ID underneath the image, and an input box (visible only on the user's own Sprite). Typing in the input box animates the Sprite image, and clicking Enter submits the message for all to see. Because the user is free to drag the Sprites around the page, the appearance is of several Sprites moving around and talking to each other, with the web page as a backdrop.

Figure 15-3. Quek


15.2.7. Code Example: DHTML Lemmings

DHTML Lemmings involves the most sophisticated use of Sprites I know of. The analysis here is only a rough summary of what's achieved. Note that the code uses some special handling for IE, which the author, Tino, explained to me is due to a bug where IE (at least some versions) bypasses the cache upon any background style change. To keep it simple, the following discussion skims overt IE-specific handling.

In DHTML Lemmings, each lemming is represented by a Lemming object, which is initialized with a number to identify the lemming and an initial position corresponding to the place where the lemming first appears on this particular level. Various other state information is also tracked:

   function Lemming(i,top,left) {     ...     this.top = top;     this.left = left;     ...     this.number = i;     ...   } 

Lemmings themselves are regular JavaScript objects and are not visible in the browser. To visually depict the lemming, a div element is created and made an attribute of the lemming, simply known as l. Thus, we might say the Lemming model "wraps" a Sprite as a means of separating semantic content from visual content. Each of these Sprites resides in the playground, an area representing the game space where the lemmings roam around. Both the playground and the Sprites are rendered with absolute positioning. Once the Sprite element has been created, event handlers are also added to support the gameplay:

   function Lemming(i,top,left) {     ...     var l = document.createElement('div');     l.number = i;     l.className = 'lemming';     l.style.top = top+'px';     l.style.left = left+'px';     ...     l.onmouseover = lemming_target_on;     l.onmouseout = lemming_target_off;     l.onmousedown = lemming_target_sel;     ..   } 

At any moment, each lemming is performing a single action, such as walking or climbing, and the action is tracked by a property of Lemming, ani. When the game begins, the lemming falls from a trapdoor, so ani is always initialized to fall:

   function Lemming(i,top,left) {     this.ani = 'fall';     ...   } 

Each type of action requires unique animation and movement. A periodic timer ticks every 60 milliseconds and updates the game's state, including each lemming's appearance and positioning. Here's how the animation works. Each action is associated with a collection of 32 x 32-pixel icons. The icons are strung together horizontally and retained in a single image. The lemming's backgroundImage style is always set to the entire image associated with its current action (Figure 15-4). Because the lemming image is set to 32 pixels, with overflow hidden, you will only ever see one of the icons. To select the appropriate icon, the backgroundPosition property is set. Thus, the backgroundImage remains fixed while the lemming is performing an action, but the backgroundPosition flows rapidly through each of the icons, beginning at zero and decrementing by 32 pixels each time until it reaches the full width of the image (as a negative value), at which point it becomes zero again.

Figure 15-4. DHTML Lemmingsbackground image used in floating sequence


Whenever the action changes, the script sets the image and initializes the position. Then, for each "tick" of the timer, the icon is advanced by altering the position of the reference image:

   Lemming.prototype.changeAnimation = function(ani) {     ...     this.pos.backgroundImage = lem[ani][this.dir];     this.pos.backgroundPosition = '0px';     ...   }   function lemming_animate(i) {     if (l.curleft == l.maxleft) l.curleft = 0;     else l.curleft -= 32;     if (ie) l.imgpos.left = l.curleft+'px';     else l.pos.backgroundPosition = l.curleft+'px';   } 

Why is the appearance changed using backgroundPosition? Wouldn't it be simpler to just run through a sequence of separate image files and alter the backgroundImage instead? Tino explains that the reason is performance: The image is held in memory, whereas image-swapping would require images to be retrieved from the cache.

As for motion, each "tick" delegates to a Strategy function (Gamma et al., 1995) for the action taking place. The Strategy function then directly manipulates the Sprite's position. So to model a lemming falling vertically, the div's top increases with each tick:

   function lemming_fall_ani(l) {       ...       l.top += 4;       ...   } 

Likewise, a walking action involves making a change to the left property:

   function lemming_walk_ani(l) {       l.left += l.dx;   } 

15.2.8. Alternatives

15.2.8.1. Tiling

Tiling is a technique in which a big image is built up from small tiles. Google Maps works this way; each map image is actually a grid of smaller image files. The benefit is that the browser will cache each tile in memory. So if you pan a little in one direction, only the new tiles need to be downloaded. Like Sprites, tiling is a technique you can use to change visual content without extracting everything from the server. And Google Maps shows that the two techniques combine effectively.

15.2.9. Related Patterns

15.2.9.1. Popup

Popup (see the next pattern) is a close cousin of Sprite. Both share the appearance of being "in front of" the rest of the document (this is typically implemented with the zIndex style), but they differ semantically. The Sprite pattern is intended to cover small objects, which are often draggable, animated, and icon-like. Often, Sprites are a standard fixture of the application, have a sense of unique identity, and remain present throughout the application. Popup is more about a transient, informational block of content that appears in order to show something or accept some input, then vanishes again. Popups tend to be larger and more text-based and are often dynamic in content.

15.2.9.2. Drag-And-Drop

Sprites can often be dragged around a space.

15.2.10. Metaphor

Think of a 20th century cartoonist creating a sequence in which a mouse walks onto a series of transparent "cel" sheets that will eventually be overlayed on a background scene.

15.2.11. Want to Know More?

  • PNG File Format (http://www.libpng.org/pub/png/pngintro.html)

15.2.12. Acknowledgments

Thanks go to Tino "Crisp" Zijdel, author of DHTML Lemmings, for clarifying the analysis in this pattern.




Ajax Design Patterns
Ajax Design Patterns
ISBN: 0596101805
EAN: 2147483647
Year: 2007
Pages: 169

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net