/******************************************************************************* FILE: mud_Scroll.js REQUIRES: prototype.js AUTHOR: Takashi Okamoto mud(tm) - http://www.mudcorp.com/ VERSION: 2.0 DATE: 01/21/2006 -------------------------------------------------------------------------------- This file is part of MudScroll. MudScroll is free for anyone to use, but this header MUST be included, and may not be modified. -------------------------------------------------------------------------------- Usage: MudScroll(id, content, contentheight, barheight, scrollheight, topOffset) options: startNum: (int) image number to start with. preload: (bool) set whether you want to initially preload images. autoplay: (int) set if you want to autoplay the image slide, and define the time for switch in seconds. default: 0 (no autoplay) *******************************************************************************/ var MudScroll = Class.create(); // LIST OF CONSTANTS/VARS var selectedObj; var offsetX, offsetY; var animateID; MudScroll.DELAY = 10; // FUNCTIONS function setSelectedElem(evt) { evt = (evt) ? evt : event; var target = (evt.target) ? evt.target : evt.srcElement; var divID = (target.id) ? target.id : target.name; if (divID) { selectedObj = $(divID); $(selectedObj).style.zIndex = 100; return; } selectedObj = null; } MudScroll.prototype = { initialize: function(id, content, contentheight, barheight, scrollheight, topOffset) { this.id = id; this.wrapper = this.id + "-wrapper"; this.content = content; this.contentheight = contentheight - barheight; this.barheight = barheight; this.scrollheight = scrollheight; this.barlength = barheight - scrollheight; this.topOffset = topOffset; this.contentscale = this.contentheight / this.barlength; this.posX = 0; this.posY = 0; this.tmpX = 0; this.tmpY = 0; this.oldX = 0; this.oldY = 0; this.scrolling = false; this.unit = 0; this.res = 20; this.frame = 0; // flag to set whether to animate when scrolling this.animation = true; }, // called onmousedown engage: function(evt) { evt = (evt) ? evt : event; setSelectedElem(evt); if (selectedObj) { this.calcOffset(evt); if (!/MSIE/.test(navigator.userAgent) || /Mac/.test(navigator.userAgent)) evt.stopPropagation(); else evt.cancelBubble = true; return false; } }, // called onmousemove drag: function(evt) { evt = (evt) ? evt : event; if (selectedObj.id != this.wrapper) { // set positions if (evt.pageY) { this.posY = evt.pageY - offsetY; } else if (evt.clientY) { this.posY = evt.clientY - offsetY - this.topOffset; } this.posX = 0; this.limitPos(); this.movePos(this.posX, this.posY); } return false; }, // called onmouseup release: function(evt) { if (selectedObj.id == this.wrapper) { evt = (evt) ? evt : event; // calculate offset this.calcOffset(evt); // setting positions this.oldX = this.posX; this.oldY = this.posY; this.posY = offsetY - this.scrollheight/2; this.posX = 0; this.limitPos(); // see if scroll animation is turned on if (this.animation) { this.animate(); } else { this.movePos(this.posX, this.posY); } } if (selectedObj) { selectedObj = null; } return false; }, scrollTo: function(px, py) { this.oldX = this.posX; this.oldY = this.posY; this.posX = px / this.contentscale; this.posY = py / this.contentscale; this.limitPos(); if (this.animation) { this.animate(); } else { this.movePos(this.posX, this.posY); } }, scrollBy: function(px, py) { this.oldX = this.posX; this.oldY = this.posY; this.posX += px; this.posY += py; this.limitPos(); if (this.animation) { this.animate(); } else { this.movePos(this.posX, this.posY); } }, animate: function() { if (animateID) animateID = null; if (!this.scrolling) { this.unitY = (this.posY - this.oldY) / this.res; this.scrolling = true; } var posX, posY; posY = this.unitY * this.frame; posX = 0; this.movePos(this.oldX + posX, this.oldY + posY); if (this.frame < this.res) { animateID = window.setTimeout(this.id + ".animate()", MudScroll.DELAY); this.frame++; } else { this.scrolling = false; this.frame = 0; } }, calcOffset: function(evt) { evt = (evt) ? evt : event; if (evt.pageX) { offsetX = evt.pageX - ((selectedObj.offsetLeft) ? selectedObj.offsetLeft : 0); if (evt.target.id == "scroll-wrapper") offsetY = evt.pageY - this.topOffset - ((selectedObj.offsetTop) ? selectedObj.offsetTop : 0); else offsetY = evt.pageY - ((selectedObj.offsetTop) ? selectedObj.offsetTop : 0); } else if (evt.offsetX) { offsetX = evt.offsetX - ((evt.offsetX < -2) ? 0 : document.body.scrollLeft); offsetY = evt.offsetY - ((evt.offsetY < -2) ? 0 : document.body.scrollTop); } else if (evt.clientX) { offsetX = evt.clientX - ((selectedObj.offsetLeft) ? selectedObj.offsetLeft : 0); offsetY = evt.clientY - ((selectedObj.offsetTop) ? selectedObj.offsetTop : 0); } // make sure offsetX, offsetY is not NaN if (isNaN(offsetX)) offsetX = 0; if (isNaN(offsetY)) offsetY = 0; }, limitPos: function() { // constrain posX to wrapper this.posY = Math.max(this.posY, 0); this.posY = Math.min(this.posY, this.barheight - this.scrollheight); // constrain posX this.posX = 0; }, movePos: function(posX, posY) { // move scroll $(this.id).style.left = posX + "px"; $(this.id).style.top = posY + "px"; // move content var contX = this.contentscale * posX; var contY = this.contentscale * posY; if (contY > 0) contY = -contY; $(this.content).style.left = -contX +"px"; $(this.content).style.top = contY + "px"; } }