DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Mac Menu Effect Js

  • submit to reddit
        Here the html code

<script src="js/prototype.js" type="text/javascript"></script>
<script src="fisheye_new_2.js" type="text/javascript"></script>
#menuBar{ width: 100%; text-align: center; position: relative; }
#menuitems { text-align: center; margin-left: auto; margin-right: auto; width: 200px; }
.menuitem { vertical-align: top; display: inline; background-color: #f00; }
.menuitem img { vertical-align: top; width: 20px; height: 20px; border: 0px; }
#logDiv { font-size: 10px; }
	<div id="menubar">
		<div id="menuitems">
			<div class="menuitem"><img onclick="alert(;" src="test2.jpg" id="img1"></div>
			<div class="menuitem"><img onclick="alert(;" src="test2.jpg" id="img2"></div>
			<div class="menuitem"><img onclick="alert(;" src="test2.jpg" id="img3"></div>
			<div class="menuitem"><img onclick="alert(;" src="test2.jpg" id="img4"></div>
			<div class="menuitem"><img onclick="alert(;" src="test2.jpg" id="img5"></div>
			<div class="menuitem"><img onclick="alert(;" src="test2.jpg" id="img6"></div>
	<div id="position"></div>
	<div id="logDiv"></div>

and the javascript, require prototypejs
var maxDist = 0;

function mousemove(e) {
	var eX =$('menuitems'))[0];
	var eY =$('menuitems'))[1];
	var eWidth = parseInt($('menuitems').getStyle('width'));
	var pX = Event.pointerX(e);
	var pY = Event.pointerY(e);
	var imgs = $('menuitems').immediateDescendants();
	for (var i = 0; i < imgs.length; i++) {
		var distFromMouse = calcDistFromMouse(pX, pY, imgs[i].firstDescendant());
		if (distFromMouse < 45) {
			var newSize = parseInt(distFromMouse * (-0.4) + 50);
			imgs[i].firstDescendant().setStyle({ width: newSize, height: newSize});
		} else {
			imgs[i].firstDescendant().setStyle({ width: 20, height: 20});

function resetScaling () {
	var imgs = $('menuitems').immediateDescendants();
	for (var i = 0; i < imgs.length; i++) {
		var newSize = 20;
		imgs[i].setStyle({ width: newSize, height: newSize});

function calcDistFromMouse(mX, mY, elem) {
	var elemCenterX = parseInt([0]) + (parseInt(elem.getStyle('width')) / 2);
	var elemCenterY = parseInt([1]) + (parseInt(elem.getStyle('height')) / 2);
	var distance = parseInt(Math.sqrt((elemCenterX - mX) * (elemCenterX - mX) + (elemCenterY - mY) * (elemCenterY - mY)));
	return distance;

function checkMousePos(pX, pY, eX, eY, eWidth ){
	if (pY - eY > 200)
		return false;
	if (pX > eX) {
		if (pX - (eX + eWidth) > 200)
			return false;
	} else {
		if (eX - pX > 200)
			return false;
	return true;

Event.observe(window,'load', function() {
  Event.observe(document,'mousemove',mousemove, false);


Snippets Manager replied on Thu, 2007/12/20 - 12:50am

unbewusstsein : The second box with the javascript is the source of the "fisheye_new_2.js" file.

Snippets Manager replied on Wed, 2007/09/19 - 5:15pm

i'd like to test your Mac Menu Effect however, where could I find the script "fisheye_new_2.js"

Snippets Manager replied on Mon, 2008/02/11 - 6:21pm

I haven't tested this code, but it could stand to be a bit more efficient. Your example is calling no less than 14 times for every twitch of the mouse (twice in the mousemove handler, and twice for each icon in calcDistFromMouse). is not a cheap function on a complex page - it loops through all the offsetParents of the target element, adding up the offsetLeft and offsetTop values. Why would you want to do this over and over again, when you could do it once in the mousemove handler, and simply store the resulting array in a variable, and pass it to the calcDistFromMouse function. Also, the mousemove handler is looking up the same element by ID no less than four times for every twitch of the mouse. Why not look it up once and save a reference in a variable? Also, is there any particular reason you're hooking in to document.mousemove instead of menubar.mousemove? Why perform all those calculations when you know for a fact the mouse isn't even over the menu bar? And I haven't tested this last bit at all, but I wonder if you might not get a smoother animation if you used the CSS zoom attribute rather than adjusting the image height and width...