/* MacStyleDock.js - a function for creating a Mac-OSX-style dock * * The author of this program, Safalra (Stephen Morley), irrevocably releases * all rights to this program, with the intention of it becoming part of the * public domain. Because this program is released into the public domain, it * comes with no warranty either expressed or implied, to the extent permitted * by law. * * For more public domain JavaScript code by the same author, visit: * * http://www.safalra.com/web-design/javascript/ */ /* Creates a MacStyleDock. A MacStyleDock is a row of images that expand as the * mouse pointer moves over them. The images are created as children of the * specified node with the specified minimum and maximum sizes. Two other * parameters specify the images to be used and the range of expansion. The * parameters are: * * node - the node at which to create the Mac-style 'dock * imageDetails - an array each of whose elements are objects with three * properties: * - name - the basename of the image * - sizes - an array of pizel sizes available * - extension - the image extension * - onclick - the function to call when the image is clicked * Requested file names consist of the concatenation of the name * property, one of the values of the size property, the string * '-reflection' for reflections, the string '-full' for full * versions (so captions can be added), and the extension * property. * minimumSize - the minimum size of icons in the dock * maximumSize - the maximum size of icons in the dock * range - the range of expansion, in icons. This must be an integer. */ function MacStyleDock(node, imageDetails, minimumSize, maximumSize, range){ var solapamiento_init = 0.2; //0.3 El rango es desde 0 - 1.33333333333333333333333333333333333333333 var solapamiento_full = 0.0; var solapamiento = solapamiento_init; var separacion = 4; // 4 var contador = 0; function pozi(){ alert(contador); } // create a container for the icons and add it to the dock container var iconsNode = document.createElement('div'); node.appendChild(iconsNode); // create a container for the reflected icons and add it to the dock container var reflectedIconsNode = document.createElement('div'); node.appendChild(reflectedIconsNode); // set the icon containers to centre its contents iconsNode.style.textAlign = 'center'; reflectedIconsNode.style.textAlign = 'center'; // set the height of the dock containers to equal that of the maximised icons iconsNode.style.height = maximumSize + 'px'; reflectedIconsNode.style.height = maximumSize + 'px'; iconsNode.style.marginRight = '-85px'; reflectedIconsNode.style.marginRight = '-85px'; // initialise the maximum width to 0 var maximumWidth = 0; // initialise the scale factor to 0 var scale = 0; // initialise the time-outs and intervals to 0 var closeTimeout = null; var closeInterval = null; var openInterval = null; // create an array to store images var images = []; // create an array to store the DOM nodes of the icons var iconNodes = []; // create an array to store the DOM nodes of reflections of the icons var reflectedIconNodes = []; // create an array to store the sizes of the icons var iconSizes = []; // Array donde dice si el icono esta maximo o no var iconMax = []; var index = 0; var iconTargets= []; // loop over the images for (var i = 0; i < imageDetails.length; i++){ // create and store a node for the icon for this image iconNodes[i] = document.createElement('img'); iconNodes[i].setAttribute('id','dock'+i); iconTargets['dock'+i] = i; // position the icon for this image relatively iconNodes[i].style.position = 'relative'; // store the initial size of the icon for this image iconSizes[i] = minimumSize; // create and store a node for the reflected icon for this image reflectedIconNodes[i] = document.createElement('img'); reflectedIconNodes[i].style.position = 'relative'; // update the properties of the icon for this image pushIconProperties(i); // add the span for this image to the dock iconsNode.appendChild(iconNodes[i]); // add the span for this image to the dock reflectedIconsNode.appendChild(reflectedIconNodes[i]); // add the appropriate event listeners to the icon for this image if (iconNodes[i].addEventListener){ iconNodes[i].addEventListener('mousemove', processMouseMove, false); iconNodes[i].addEventListener('mouseout', processMouseOut, false); iconNodes[i].addEventListener('click', imageDetails[i].onclick, false); iconNodes[i].style.cursor = 'pointer'; //iconNodes[i].addEventListener('click', pozi, false); }else if (iconNodes[i].attachEvent){ iconNodes[i].attachEvent('onmousemove', processMouseMove); iconNodes[i].attachEvent('onmouseout', processMouseOut); iconNodes[i].attachEvent('onclick', imageDetails[i].onclick); } // loop over the sizes available for this image for (var j = 0; j < imageDetails[i].sizes.length; j++){ // create a DOM node containing this image at this size var image = document.createElement('img'); image.setAttribute( 'src', imageDetails[i].name + imageDetails[i].sizes[j] + imageDetails[i].extension); // add the DOM node to the array of stored images images.push(image); } } function pushIconProperties(index){ var frj = imageDetails[index]; // set the src attribute of the image for the icon iconNodes[index].setAttribute('src', frj.name + frj.sizes[0] + frj.extension); // set the src attribute of the image for the icon's reflection reflectedIconNodes[index].setAttribute('src', frj.name + frj.sizes[0] + '-reflection' + frj.extension); iconMax[index] = 0; reflectedIconNodes[index].setAttribute('width', minimumSize); iconNodes[index].setAttribute('width', minimumSize); reflectedIconNodes[index].setAttribute('height', minimumSize); iconNodes[index].setAttribute('height', minimumSize); // set the top margin of the image for the icon iconNodes[index].style.marginTop = (maximumSize - minimumSize) + 'px'; reflectedIconNodes[index].style.marginBottom = (maximumSize - minimumSize) + 'px'; if(index==imageDetails.length-1) { iconNodes[index].style.marginRight = '0px'; reflectedIconNodes[index].style.marginRight = '0px'; iconNodes[index].style.marginLeft = -(maximumSize-minimumSize)*solapamiento+'px'; reflectedIconNodes[index].style.marginLeft = -(maximumSize-minimumSize)*solapamiento+'px'; } else if (index==0) { iconNodes[index].style.marginRight = -(maximumSize-minimumSize)*solapamiento+'px'; reflectedIconNodes[index].style.marginRight = -(maximumSize-minimumSize)*solapamiento+'px'; iconNodes[index].style.marginLeft = '0px'; reflectedIconNodes[index].style.marginLeft = '0px'; } else { iconNodes[index].style.marginRight = -(maximumSize-minimumSize)*solapamiento+'px'; reflectedIconNodes[index].style.marginRight = -(maximumSize-minimumSize)*solapamiento+'px'; iconNodes[index].style.marginLeft = -(maximumSize-minimumSize)*solapamiento+'px'; reflectedIconNodes[index].style.marginLeft = -(maximumSize-minimumSize)*solapamiento+'px'; } } /* Sets a toolbar image to the specified size. The parameter is: * * index - the 0-based index of the image to be sized */ function updateIconProperties(index){ // determine the size for the icon, taking into account the scale factor var size = Math.round(minimumSize + scale * (iconSizes[index] - minimumSize)); //FRJ if (size!=iconNodes[index].width){ var frj = imageDetails[index]; // check whether the full icon with its caption should be displayed if ((size == maximumSize)&&(iconMax[index]==2)){ iconMax[index] = 1; // set the src attribute of the image for the icon iconNodes[index].setAttribute('src', frj.name + maximumSize + '-full' + imageDetails[index].extension); iconNodes[index].style.marginLeft = separacion*scale+'px'; reflectedIconNodes[index].style.marginLeft = separacion*scale+'px'; iconNodes[index].style.marginRight = separacion*scale+'px'; reflectedIconNodes[index].style.marginRight = separacion*scale+'px'; /*} else if ((size != maximumSize)&&(iconMax[index]==1)){ iconMax[index] = 2; } else if ((size != maximumSize)&&(iconMax[index]==0)){ */ } else if ((size != maximumSize)&&(iconMax[index]!=2)){ iconMax[index] = 2; iconNodes[index].setAttribute('src', frj.name + frj.sizes[1] + frj.extension); reflectedIconNodes[index].setAttribute('src', frj.name + frj.sizes[1] + '-reflection' + frj.extension); } else if (size == minimumSize){ iconMax[index] = 0; iconNodes[index].setAttribute('src', frj.name + frj.sizes[0] + frj.extension); reflectedIconNodes[index].setAttribute('src', frj.name + frj.sizes[0] + '-reflection' + frj.extension); } // set the width and height of the image for the icon and its reflection reflectedIconNodes[index].setAttribute('width', size); iconNodes[index].setAttribute('width', size); reflectedIconNodes[index].setAttribute('height', size); iconNodes[index].setAttribute('height', size); // set the top margin of the image for the icon iconNodes[index].style.marginTop = (maximumSize - size) + 'px'; reflectedIconNodes[index].style.marginBottom = (maximumSize - size) + 'px'; if (size != maximumSize){ //FRJ if(index==imageDetails.length-1) { iconNodes[index].style.marginRight = '0px'; reflectedIconNodes[index].style.marginRight = '0px'; iconNodes[index].style.marginLeft = -(maximumSize-size)*solapamiento+'px'; reflectedIconNodes[index].style.marginLeft = -(maximumSize-size)*solapamiento+'px'; } else if (index==0) { iconNodes[index].style.marginRight = -(maximumSize-size)*solapamiento+'px'; reflectedIconNodes[index].style.marginRight = -(maximumSize-size)*solapamiento+'px'; iconNodes[index].style.marginLeft = '0px'; reflectedIconNodes[index].style.marginLeft = '0px'; } else { iconNodes[index].style.marginRight = -(maximumSize-size)*solapamiento+'px'; reflectedIconNodes[index].style.marginRight = -(maximumSize-size)*solapamiento+'px'; iconNodes[index].style.marginLeft = -(maximumSize-size)*solapamiento+'px'; reflectedIconNodes[index].style.marginLeft = -(maximumSize-size)*solapamiento+'px'; } } //FRJ } } /* Processes a mousemove event on an image in the 'dock'. The parameter is: * * e - the event object. window.event will be used if this is undefined. */ function processMouseMove(e){ // clear the closing interval and time-out window.clearTimeout(closeTimeout); closeTimeout = null; window.clearInterval(closeInterval); closeInterval = null; //} // check that the opening interval is required but does not yet exist if (scale != 1 && !openInterval){ // create the opening interval openInterval = window.setInterval( function(){ if (scale < 1) scale += 0.125; if (scale >= 1){ scale = 1; window.clearInterval(openInterval); openInterval = null; } for (var i = 0; i < iconNodes.length; i++){ updateIconProperties(i); } }, 20); } // set the event object if the browser does not supply it if (!e) e = window.event; // find the DOM node on which the mouseover event occured var target = e.target || e.srcElement; if(iconTargets[index]!=target.id){ // obtain the index of the icon on which the mouseover event occured index = iconTargets[target.id]; } // obtain the fraction across the icon that the mouseover event occurred var across = (e.layerX || e.offsetX) / iconSizes[index]; // check a distance across the icon was found (in some cases it will not be) if (across){ // initialise the current width to 0 var currentWidth = 0; // loop over the icons for (var i = 0; i < iconNodes.length; i++){ // check whether the icon is in the range to be resized if (i < index - range || i > index + range){ // set the icon size to the minimum size iconSizes[i] = minimumSize; }else if (i == index){ // set the icon size to be the maximum size iconSizes[i] = maximumSize; }else if (i < index){ // set the icon size to the appropriate value iconSizes[i] = minimumSize + Math.round( (maximumSize - minimumSize - 1) * ( Math.cos( (i - index - across + 1) / range * Math.PI) + 1) / 2); // add the icon size to the current width currentWidth += iconSizes[i]; }else{ // set the icon size to the appropriate value iconSizes[i] = minimumSize + Math.round( (maximumSize - minimumSize - 1) * ( Math.cos( (i - index - across) / range * Math.PI) + 1) / 2); // add the icon size to the current width currentWidth += iconSizes[i]; } } // update the maximum width if necessary if (currentWidth > maximumWidth) maximumWidth = currentWidth; // detect if the total size should be corrected if (index >= range && index < iconSizes.length - range && currentWidth < maximumWidth){ // correct the size of the smallest magnified icons iconSizes[index - range] += Math.floor((maximumWidth - currentWidth) / 2); iconSizes[index + range] += Math.ceil((maximumWidth - currentWidth) / 2); } // update the sizes of the images if ( openInterval == null){ //FRJ for (var i = 0; i < iconNodes.length; i++) updateIconProperties(i); } //FRJ } } // Processes a mouseout event on an image in the dock. function processMouseOut(){ // check that neither the closing interval nor time-out are set if ((closeTimeout==null) && (closeInterval==null)){ // create the closing time-out closeTimeout = window.setTimeout( function(){ closeTimeout = null; if (openInterval){ window.clearInterval(openInterval); openInterval = null; } closeInterval = window.setInterval( function() { if (scale > 0) scale -= 0.125; if (scale <= 0){ scale = 0; window.clearInterval(closeInterval); closeInterval = null; } // update the sizes of the images for (var i = 0; i < iconNodes.length; i++) updateIconProperties(i); }, 20); }, 150); } } }