Recent Weblogs

Links I like

A Fisheye for the Prototypejs Community

A Measurement of proximity to determine the magnification of the icon

What is a Fisheye?

The idea behind a fisheye control is a strip of icons, being vertical or horizontally laid out that reacts to the user's mouse as it approaches the icon. This control was made popular by Mac OSX "Dock".

Why use a Fisheye

It improves usability and reinforces to the user that this is an interactive component which is ready to respond to the user's action.

How do I use this Fisheye?

While there are plenty of implementations of this control, which I will link to at the bottom of the article. I believe this approach leaves less stress for the implementor than most. It of course uses prototype and harnesses the DOM Extension methods to enhance performance and reliability across the browser board. It also uses an event style architecture to allow for convienence of attaching methods to a particular item being clicked etc.

How can I extend this Fisheye?

As noted previously the component is built using prototypejs, the class structure allows itself to be extended very easily through techniques of inheritance. I've also attempted to insert a few hooks to make extension even easier, this is very similar to Thomas Fuchs' implementation of Effects and his options argument to allow for a form of composition.


The component only effects three attributes, height, width and marginTop. Height and width im sure you expected but why bother with marginTop? Because if that isn't calculated in the scaling, as one grows to max height it will push all other icons in the toolbar down which creates a kind of "bouncing" effect, trust me it isn't pretty.

An HTML Microformat

The FishEyeToolBar class is expecting a specific microformat to work with, starting from the container, is expecting a list of img tags that will act as the icon to be scaled. You can modify this expectation to any CSS selector that descends from the root element by customizing the selector property in the options argument.

The Sword of CSS

So we've got HTML and Javascript at work here, but CSS has a pretty big role in implementing a smooth fisheye. The first big tip is to make sure you're FishEye element has the property text-align:center; this will make sure as the images scale that they stay centered! In my first attempts i was trying to calculate this myself, talk about a headache. Next is a proper marginTop As noted above you can get some horrid looking bouncing effect if this isn't set right, my rule of thumb is set the marginTop to be at least the height of the image that way as the image comes up to double its original height, it will have some margin to eat up before it starts to push the others down.


The FishEyeToolBar class acts as the super class, it listens to the mouseMove event on the containing object and collects the img elements to be constructed into FishEyeItem objects.

FishEyeToolBar options

	 selector : "img", // the selector that FishEyeToolBar uses to collect its icons.
	 createSub : this.createSub.bind(this), //Allows for a custom factory function to create the FishEyeItem object, or whatever you extend from it.
	 subOptions : {} // for convienence allows you to send options argument to the default createSub method.


The FishEyeItem class acts as a wrapper class for an img element. It provides easier, encapsulated logic to allow for less work by the FishEyeToolBar class.

FishEyeItem options

	scaleThrottle : 200

The scale throttle is pretty simple, it basically acts as the judge for saying is this mouseMovement within my range? If so it will calculate a value between 1 and 2 as a percentage to increase the icon by, the larger the throttle the bigger the effected proximity will be but this will in turn make for a slower, potentially smoother animation, this is something you'll have to mess with to truely perceive.


In order for the class objects to communicate with other objects they have inherited from the EventDispatcher class. This class was my attempt at custom events, but in the end just turned into a great class for implementing an observer pattern.


Looking for a working example? Inspired by the many comments below I have developed a page purely for the purpose of providing a demo. In further development I've also created a subclass to handle the behavior of a fisheye resting on the upper edge of a page that would need to expand down instead of up, check out the demo and you'll see what I mean.


Download prototype FishEye
This was a great project and although i am certainly not an animation designer/programmer i was able to produce the desired behavior by relying on the DOM and a decent observer pattern. I urge you to take a look at the source and produce your own algorithms for scaling, mine is quite vanilla, you'd just have to override the handleFishEye method in the FishEyeItem class.

Related Links


Warning: mysql_connect() [function.mysql-connect]: Access denied for user 'mfoster'@'' (using password: YES) in /home/content/m/a/t/mattfoster01/html/includes/php_common/lib/classes/abstract.mySQL.php on line 15

Fatal error: Uncaught exception 'Exception' with message 'Failed to connect to mySQL server in method : mySQLBase::connect' in /home/content/m/a/t/mattfoster01/html/includes/php_common/lib/classes/abstract.mySQL.php:16 Stack trace: #0 /home/content/m/a/t/mattfoster01/html/includes/template/comment.php(29): mySQLBase->connect('', 'mfoster', 'havef8th') #1 /home/content/m/a/t/mattfoster01/html/blog/2007/08/prototype-fisheye.php(181): include_once('/home/content/m...') #2 {main} thrown in /home/content/m/a/t/mattfoster01/html/includes/php_common/lib/classes/abstract.mySQL.php on line 16