{\rtf1\ansi\ansicpg1252\cocoartf2636 \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fmodern\fcharset0 Courier;} {\colortbl;\red255\green255\blue255;\red0\green0\blue0;} {\*\expandedcolortbl;;\cssrgb\c0\c0\c0;} \paperw11900\paperh16840\margl1440\margr1440\vieww11520\viewh8400\viewkind0 \deftab720 \pard\pardeftab720\partightenfactor0 \f0\fs26 \cf0 \expnd0\expndtw0\kerning0 \outl0\strokewidth0 \strokec2 /**********************************************************************\ 3D image rotating script\ By Mark Wilton-Jones 04-05/1/2007\ Version 1.0\ ***********************************************************************\ \ Please see http://www.howtocreate.co.uk/jslibs/ for details and a demo of this script\ Please see http://www.howtocreate.co.uk/tutorials/jsexamples/imagerotate.html for configuration instructions\ Please see http://www.howtocreate.co.uk/jslibs/termsOfUse.html for terms of use\ \ ________________________________________________________________________________*/\ \ function rotatingImageError(rotError,useThrow) \{\ rotError = \{ name: 'RotatingImage error', message: rotError, description: rotError \};\ if( useThrow ) \{ eval('throw(rotError)'); \} else \{ alert( rotError.name + ': ' + rotError.message ); \}\ \}\ \ function getRotPositionFromEvent(mousEvent) \{\ if( typeof( mousEvent.pageX ) != 'undefined' ) \{\ return [mousEvent.pageX,mousEvent.pageY];\ \} else \{\ var startX = mousEvent.clientX, startY = mousEvent.clientY;\ if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) \{\ return [startX+document.documentElement.scrollLeft,startY+document.documentElement.scrollTop];\ \} else \{\ return [startX+document.body.scrollLeft,startY+document.body.scrollTop];\ \}\ \}\ \}\ \ function RotatingImage( imgPrefix, imgExt, imgName, numRot, numTilt, curRot, curTilt, progressScript, oReadyScript, useThrow ) \{\ \ //check for errors\ var rotError = '';\ if( !this.startAutoRot ) \{ rotError += '\\n* Use the \\'new\\' keyword when calling the RotatingImage function.'; \}\ if( typeof(imgPrefix) != 'string' ) \{ rotError += '\\n* Image prefix must be a string.'; \}\ if( typeof(imgExt) != 'string' ) \{ rotError += '\\n* Image extension must be a string.'; \}\ if( typeof(imgName) != 'string' ) \{ rotError += '\\n* Image name must be a string.'; \}\ if( RotatingImage.prototype.doneImages[imgName] ) \{ rotError += '\\n* Image name'+imgName+' has already been set up ready to rotate. This cannot be done twice for a single image.'; \}\ if( isNaN(numRot) || numRot < 1 || parseInt(numRot) != numRot ) \{ rotError += '\\n* Number of images in the rotation must be a whole number >= 1.'; \}\ if( isNaN(numTilt) || numTilt < 1 || parseInt(numTilt) != numTilt ) \{ rotError += '\\n* Number of tilt angles must be a whole number >= 1.'; \}\ if( isNaN(curRot) || curRot < 1 || curRot > numRot || parseInt(curRot) != curRot ) \{ rotError += '\\n* Current rotation must be a whole number between 1 and the number of images in the rotation.'; \}\ if( isNaN(curTilt) || curTilt < 1 || curTilt > numTilt || parseInt(curTilt) != curTilt ) \{ rotError += '\\n* Current tilt must be a whole number between 1 and the number of tilt angles.'; \}\ if( rotError ) \{ rotatingImageError(rotError,useThrow); return; \}\ RotatingImage.prototype.doneImages[imgName] = true;\ \ //store values\ this.imgPrefix = imgPrefix;\ this.imgExt = imgExt;\ this.imgName = imgName;\ this.numRot = numRot;\ this.numTilt = numTilt;\ this.curRot = curRot;\ this.curTilt = curTilt;\ this.useThrow = useThrow;\ \ //prepare automation\ this.rotInterval = 0;\ this.tiltInterval = 0;\ this.pausedX = false;\ this.pausedY = false;\ \ //begin preloading required images - this could take a while :)\ this.preloadComplete = false;\ this.imagesLoaded = 0;\ this.imageCache = [];\ var rotref = this;\ for( var i = 1; i <= numRot; i++ ) \{\ this.imageCache[i] = [];\ for( var j = 1; j <= numTilt; j++ ) \{\ //index 0 is unused in both array levels\ //this is harmless but makes it easier to use later without having to add and subtract 1 (so it is more efficient)\ this.imageCache[i][j] = new Image();\ this.imageCache[i][j].onload = (function (theImage) \{ return function () \{\ if( theImage.alreadyload ) \{ return; \}\ theImage.alreadyload = true;\ rotref.imagesLoaded++;\ if( progressScript ) \{ progressScript( rotref.imagesLoaded / ( rotref.numRot * rotref.numTilt ) ); \}\ if( rotref.imagesLoaded == rotref.numRot * rotref.numTilt ) \{\ if( oReadyScript ) \{ oReadyScript(); \}\ rotref.preloadComplete = true;\ \}\ \}; \})(this.imageCache[i][j]); //workaround for Safari stupidity ('this' points to window)\ this.imageCache[i][j].onerror = function () \{ this.onload(); \};\ this.imageCache[i][j].src = this.imgPrefix + '_' + i + '_' + j + this.imgExt;\ if( this.imageCache[i][j].complete ) \{ this.imageCache[i][j].onload(); \}\ \}\ \}\ \}\ RotatingImage.prototype.doneImages = \{\};\ \ //general redraw\ RotatingImage.prototype.redraw = function () \{\ if( !this.image ) \{ this.image = document.images[this.imgName]; if( !this.image ) \{ return; \} \}\ this.image.src = this.imageCache[this.curRot][this.curTilt].src;\ \};\ \ //automation\ RotatingImage.prototype.startAutoTilt = function (oTime,oStartDir) \{\ var oOb = this;\ if( this.numTilt < 2 ) \{\ rotatingImageError('AutoTilt can only be used if more than one tilt angles are being used.',this.useThrow); return;\ \}\ if( isNaN(oTime) || oTime < 10 || parseInt(oTime) != oTime ) \{\ rotatingImageError('AutoTilt needs to be passed an integer greater than 10 to use as the stepping interval.',this.useThrow); return;\ \}\ this.stopAutoTilt();\ this.tiltDirection = oStartDir;\ this.tiltInterval = setInterval(function () \{\ if( oOb.preloadComplete && !oOb.pausedY && ( oOb.image || document.images[oOb.imgName] ) ) \{\ if( oOb.tiltDirection && oOb.curTilt == oOb.numTilt ) \{ oOb.tiltDirection = false; \}\ if( !oOb.tiltDirection && oOb.curTilt == 1 ) \{ oOb.tiltDirection = true; \}\ if( oOb.tiltDirection ) \{ oOb.tiltUp(true); \} else \{ oOb.tiltDown(true); \}\ \}\ \},oTime);\ \};\ RotatingImage.prototype.stopAutoTilt = function () \{\ if( this.tiltInterval ) \{\ clearInterval(this.tiltInterval);\ this.tiltInterval = 0;\ \}\ \};\ RotatingImage.prototype.startAutoRot = function (oTime,oDir) \{\ var oOb = this;\ if( isNaN(oTime) || oTime < 10 || parseInt(oTime) != oTime ) \{\ rotatingImageError('AutoRotate needs to be passed an integer greater than 10 to use as the stepping interval.',this.useThrow); return;\ \}\ this.stopAutoRot();\ this.rotDirection = oDir;\ this.rotInterval = setInterval(function () \{\ if( oOb.preloadComplete && !oOb.pausedX && ( oOb.image || document.images[oOb.imgName] ) ) \{\ if( oOb.rotDirection ) \{ oOb.rotateUp(true); \} else \{ oOb.rotateDown(true); \}\ \}\ \},oTime);\ \};\ RotatingImage.prototype.stopAutoRot = function () \{\ if( this.rotInterval ) \{\ clearInterval(this.rotInterval);\ this.rotInterval = 0;\ \}\ \};\ \ //individual tilt/rotation\ RotatingImage.prototype.tiltTo = function (oTilt,oAllow) \{\ if( !oAllow ) \{ this.stopAutoTilt(); \}\ if( isNaN(oTilt) || oTilt < 1 || oTilt > this.numTilt || parseInt(oTilt) != oTilt ) \{\ rotatingImageError('tiltTo number must be a whole number between 1 and the number of tilt angles.',this.useThrow); return;\ \}\ this.curTilt = oTilt;\ this.redraw();\ \};\ RotatingImage.prototype.tiltUp = function (oAllow) \{\ if( !oAllow ) \{ this.stopAutoTilt(); \}\ if( this.curTilt < this.numTilt ) \{\ this.curTilt++;\ this.redraw();\ \}\ \};\ RotatingImage.prototype.tiltDown = function (oAllow) \{\ if( !oAllow ) \{ this.stopAutoTilt(); \}\ if( this.curTilt > 1 ) \{\ this.curTilt--;\ this.redraw();\ \}\ \};\ RotatingImage.prototype.rotateTo = function (oRot,oAllow) \{\ if( !oAllow ) \{ this.stopAutoRot(); \}\ if( isNaN(oRot) || oRot < 1 || oRot > this.numRot || parseInt(oRot) != oRot ) \{\ rotatingImageError('rotateTo number must be a whole number between 1 and the number of images in the rotation.',this.useThrow); return;\ \}\ this.curRot = oRot;\ this.redraw();\ \};\ RotatingImage.prototype.rotateUp = function (oAllow) \{\ if( !oAllow ) \{ this.stopAutoRot(); \}\ this.curRot++;\ if( this.curRot > this.numRot ) \{ this.curRot = 1; \}\ this.redraw();\ \};\ RotatingImage.prototype.rotateDown = function (oAllow) \{\ if( !oAllow ) \{ this.stopAutoRot(); \}\ this.curRot--;\ if( !this.curRot ) \{ this.curRot = this.numRot; \}\ this.redraw();\ \};\ \ //panning\ RotatingImage.prototype.setPanning = function (oX,oY,oStopX,oStopY) \{\ var oOb = this;\ if( !this.image ) \{ this.image = document.images[this.imgName]; if( !this.image ) \{\ rotatingImageError('Panning cannot be allowed until after the image has been created.',this.useThrow); return;\ \} \}\ if( !oX && !oY ) \{\ this.image.onmousedown = null;\ if( this.image.style ) \{ this.image.style.cursor = ''; \}\ return;\ \}\ if( this.image.style ) \{ this.image.style.cursor = 'move'; \}\ this.image.ondragstart = function () \{ return false; \}\ this.image.onselectstart = function () \{ return false; \}\ this.image.onmousedown = function (e) \{\ if( !e ) \{ e = window.event; \} if( !e ) \{ return true; \}\ if( e.button > 1 || e.which > 1 ) \{ return true; \}\ var startRotImg = oOb.curtRot, startTiltImg = oOb.curtTilt, startPos = getRotPositionFromEvent(e), oldmouseup = document.onmouseup, curSegs = [0,0];\ this.onmousemove = function (e) \{\ if( !e ) \{ e = window.event; \}\ var newSegs = [ this.width / ( oOb.numRot / 2 ), this.height / oOb.numTilt ];\ var mousePos = getRotPositionFromEvent(e);\ newSegs[2] = newSegs[0] = Math.round( ( mousePos[0] - startPos[0] ) / newSegs[0] );\ newSegs[3] = newSegs[1] = Math.round( ( mousePos[1] - startPos[1] ) / newSegs[1] );\ if( oX ) \{\ if( oStopX ) \{ oOb.stopAutoRot(); \}\ oOb.pausedX = true;\ while( newSegs[0] > curSegs[0] ) \{ oOb.rotateDown(!oStopX); newSegs[0]--; \}\ while( newSegs[0] < curSegs[0] ) \{ oOb.rotateUp(!oStopX); newSegs[0]++; \}\ \}\ if( oY ) \{\ if( oStopY ) \{ oOb.stopAutoTilt(); \}\ oOb.pausedY = true;\ while( newSegs[1] > curSegs[1] ) \{ oOb.tiltDown(!oStopY); newSegs[1]--; \}\ while( newSegs[1] < curSegs[1] ) \{ oOb.tiltUp(!oStopY); newSegs[1]++; \}\ \}\ curSegs = [newSegs[2],newSegs[3]];\ \};\ document.onmouseup = function () \{\ oOb.pausedX = false;\ oOb.pausedY = false;\ oOb.image.onmousemove = null;\ document.onmouseup = oldmouseup;\ \};\ return false;\ \};\ \};\ \ //zooming\ RotatingImage.prototype.setupZoomInformation = function() \{ if( !this.image ) \{ this.image = document.images[this.imgName]; if( !this.image ) \{\ rotatingImageError('Images cannot be zoomed until after they have been created.',this.useThrow); return;\ \} \}\ if( !this.rotZoomDetails ) \{\ if( !this.image.height && !this.image.width ) \{\ rotatingImageError('Images cannot be zoomed until after they have loaded.',this.useThrow); return;\ \}\ this.rotZoomDetails = \{ height: this.image.height, width: this.image.width, zoom: 100 \};\ \}\ \}\ RotatingImage.prototype.zoomImageIn = function (byPercent,maxPercent) \{\ this.setupZoomInformation();\ if( !this.rotZoomDetails ) \{ return 0; \}\ var desiredPercent = this.rotZoomDetails.zoom + byPercent;\ if( desiredPercent > maxPercent ) \{ desiredPercent = maxPercent; \}\ this.zoomImageTo(desiredPercent);\ return desiredPercent;\ \}\ RotatingImage.prototype.zoomImageOut = function (byPercent,minPercent) \{\ this.setupZoomInformation();\ if( !this.rotZoomDetails ) \{ return 0; \}\ var desiredPercent = this.rotZoomDetails.zoom - byPercent;\ if( desiredPercent < minPercent ) \{ desiredPercent = minPercent; \}\ this.zoomImageTo(desiredPercent);\ return desiredPercent;\ \}\ RotatingImage.prototype.zoomImageTo = function (toPercent) \{\ this.setupZoomInformation();\ if( !this.rotZoomDetails ) \{ return; \}\ if( isNaN(toPercent) || toPercent < 0 ) \{ rotatingImageError('A positive number must be used when zooming.',this.useThrow); return; \}\ this.image.height = Math.round( this.rotZoomDetails.height * ( toPercent / 100 ) );\ this.image.width = Math.round( this.rotZoomDetails.width * ( toPercent / 100 ) );\ this.rotZoomDetails.zoom = toPercent;\ \}\ \ //simulated read-only properties\ RotatingImage.prototype.getTilt = function () \{ return this.curTilt; \};\ RotatingImage.prototype.getNumTilt = function () \{ return this.numTilt; \};\ RotatingImage.prototype.getRotation = function () \{ return this.curRot; \};\ RotatingImage.prototype.getNumRotation = function () \{ return this.numRot; \};\ }