Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / XHTML

MS Agent style critters for your web pages

4.53/5 (23 votes)
13 Feb 2009BSD6 min read 1   450  
Implementing MS Agent style critters for your web pages.

jcritter.png

Introduction

This is an MS Agent style class for web pages. It uses JavaScript and (X)HTML only. No Active-X or other plug-ins are required.

Background

I recently needed a way to communicate with the users of a web page via a somewhat "interactive" manner, without using Flash or Java. Alert boxes were simply too obtrusive. I thought about MS Agent, but then it would only be compatible with IE. So I decided to build my own that would, in part, mimic the functionality of MS Agent, but be as cross-browser as possible.

Using the Code

The class itself is pretty easy to use. You supply your own image and small adjustments to make sure everything goes where you want to.

JavaScript
<script src="jcritter.js" type="text/javascript"></script>

<script type="text/javascript">
    var newCritter;
    window.onload =    function()
    {
    var monkey = 
    {
        width: 128,
        height: 128,
        src: 'monkey.gif',
        adjustTop: 15,
        adjustLeft: 20,
        speechTop: 45,
        speechLeft: 65

    }
    myCritter = new JCritter(monkey);
    myCritter.draw();
    myCritter.show();
    }
    
</script>

You can also use jcritter-mini.js or jcritter-micro.js. jcritter-mini.js is a minimized version with comments and white spaces removed. jcritter-micro.js is an extremely compact version and the code is obfuscated slightly. jcritter-mini.js and jcritter-micro.js are about half to one third the size of the original jcritter.js.

Properties

You shouldn't set any of these. They are included so you can test the current state of your critter.

  • JCritter.version: Display JCritter version.
  • JCritter.isHidden: Boolean value. Shows current display state of the critter.
  • JCritter.isSpeaking: Boolean value. Shows current speaking state of the critter.

Methods

  • JCritter.drawAgent(): Draws the agent on the screen. Shouldn't need to use it.
  • JCritter.drawBalloon(): Draws the balloon on the screen. Shouldn't need to use it.
  • JCritter.draw(): Draws both the balloon and critter. Use it after creation or to realign your critter.
  • JCritter.say(text, alignment): Shows the balloon and says the desired text. alignment is optional and can be any valid CSS 'text-alignment' value. If say is called with no arguments, the contents of the balloon are returned.
  • JCritter.hush(): Removes the balloon.
  • JCritter.show(): Shows the critter.
  • JCritter.hide(): Hides the critter and balloon.
  • JCritter.mute(): Mutes the critter. The critter will ignore the say method until unMute is called.
  • JCritter.unMute(): Unmutes the critter
  • JCritterdestroy(): Destroys the critter object. You'll probably want to call this on your body's onunload event.
  • JCritter.play(animationName): Switches the current image to the image specified by the animation name. Used with animated GIFs, you can provide your own ad-hoc animations.
  • JCritter.setFontSize(size): Sets the font size.
  • JCritter.setFontColor(color): Sets the font color.
  • JCritter.setAgent(agent): Sets the current agent to agent.

Events

All events can be set using the standard JavaScript method:

JavaScript
object.eventname = function()
{ 
    //do stuff
}
  • JCritter.onClick: Called when the critter is clicked.
  • JCritter.onMouseIn: Called when the mouse enters the critter's boundaries.
  • JCritter.onMouseOut: Called when the mouse moves outside the critter boundaries.

Custom

It's possible to add your own custom critter images, rather than using the default image that comes with the script. Since it's impossible to determine the exact placement of the speech bubble outside the square boundary of the image itself, several options have been provided to allow you to "fine tune" the placement of the balloon. All of these adjustments are relative to the top left corner of the critter. You create a JavaScript object with the properties and pass it to the JCritter constructor.

JavaScript
//Add your own custom critters!

var penguin = 
{
    width: 112,
    height: 112,
    src: 'penguin.gif',
    adjustTop: 15,
    adjustLeft: 20,
    speechTop: 25,
    speechLeft: 65 
    animations:
    {
        animation_name: 'animation_image.gif'

    }
}
  • width: The width of your critter.
  • height: The height of your critter.
  • src: The image source of your critter.
  • adjustTop: Adjustment of your critter from the top of the viewing area.
  • adjustLeft: Adjustment of your critter from the left of the viewing area.
  • speechTop: Adjustment of your balloon from the top of your critter.
  • speechLeft: Adjustment of your balloon from the left of your critter.
  • animations: An object containing a list of animation names and an image to coincide with the animations.

Animations

If you supply numerous GIF images (probably animated), you can fake some animation. The big drawback to this is that JavaScript is not capable of knowing when an animation "ends". Because of this, you will want to be careful using looping animations, and your animations should return to the default image you want to display when your critter is idle.

JavaScript
animations:
{
    name: imagesrc,
    name2: imagesrc,
    name3: imagesrc
}
...
JCritter.play('name3'); 

Technique

The first thing we must do is create our DIVs that will hold the elements we work with. We will be using five DIVs. The first DIV will contain DIVs 2-4. It will hold the bubble image and a DIV for the text image. The last DIV will contain the image of the agent or critter that will be speaking.

The two "main" DIVs are outlined in black

critter_div_diagram.png

The three DIVs that make up the bubble DIV

bubble_diagram.png

The actual bubble DIV

bubble.gif

As you can see, the bubble image is much large than what we need. This is to accommodate large amounts of text. In order to accomplish this, we use a technique called "sliding doors". Using CSS, we will set the background image of the red and green DIV to the top and bottom of the bubble image, respectively.

JavaScript
//the top bubble in red
bubbleTop.style.background = 'url(bubble.gif) no-repeat top';
bubbleTop.style.padding = '25px 8px 0px';

//the bottom bubble in green
bubbleBottom.style.background = 'url(bubble.gif) no-repeat bottom';
bubbleBottom.style.padding = '35px 8px 0px';

You'll notice the bubble is now complete, but there is no text. We need to have a DIV between the top and bottom with a bit of padding on the left and right.

JavaScript
//the bubble text in blue
bubbleText.style.paddingLeft = '10px';
bubbleText.style.paddingRight = '10px';

Now the only real issue left is positioning. The critter/agent needs to be placed in the bottom left corner of the view port. Unfortunately, there is no built-in mechanism to get the view port of a browser window, so after searching the web a bit, I managed to find some code that will identify this allusive property.

JavaScript
//the width of the viewport
window.innerWidth || (document.documentElement.clientWidth || (document.body.clientWidth || 0));

//the height of the viewport
window.innerHeight || (document.documentElement.clientHeight || (document.body.clientHeight || 0));

If all of our checks fail, we'll return an x and y of 0. This isn't ideal, but it's better than returning nothing, which will certainly break the script.

Now that we know the width and height of our view port, we can subtract the width and height of our critter/agent. This will allow us to place it in the corner of the screen. We have to add a few cosmetic pixels here or there to position it as desired. Once the critter/agent is in place, the word balloon can be positioned. The default positioning is relative to the top left corner of the DIV that contains the critter/agent. Since it's impossible to automatically know what our image looks like (where the mouth is, etc.), we adjust our balloon using the speechLeft and speechTop options specified when we created our agent.

Once everything is positioned, we just need to set the properties of our two "master" DIVs to hidden/visible whenever we need to show/hide the critter/agent or the speech balloon.

Compatibility

  • Image 5Firefox
  • Image 6Internet Explorer 7
  • Image 7Internet Explorer 6
  • Image 8Opera
  • Image 9Safari
  • Image 10Konqueror

Bugs

  • Positioning can get screwed up when using targets. You have to use draw to fix or scroll/resize the page (forces a redraw).

Points of Interest

This code works best on "Web 2.0" sites, where pages are not forced to refresh as often. IE6 doesn't support the fixed property. As a result, whenever the script detects that the user is using the IE6 browser, it will change the position to absolute, and add the draw() method to the window.onscroll callback. If you resize your window, you will need to call the draw() method again to realign your critter.

History

  • Wednesday, October 22, 2008: Updated article. Updated zip file with minimized versions. Random bug fixes.
  • Friday, September 5, 2008: Updated article.
  • Tuesday, June 10 2008: Updated article.
  • Monday, April 28 2008 : Updated article.
  • Wednesday, March 5 2008: Restored article (what the heck?).
  • Tuesday, October 23 2007: Restored article (deleted accidentally).
  • Tuesday, October 17 2007: Uploaded Version 0.5.
    • Animation support added.
    • Removed event handlers on Destroy.
  • Tuesday, October 16 2007: Uploaded Version 0.4.

License

This article, along with any associated source code and files, is licensed under The BSD License