// --------------------------------------- // abgekippt.de javascript lib // Implemented by Juergen Preuss // // copyright 2008 Juergen Preuss // --------------------------------------- // --------------------------------------- // Vector // --------------------------------------- function Vector(x,y) { this.x = x; this.y = y; // --------------------------------------- // // --------------------------------------- this.add=function(delta) { this.x+=delta.x; this.y+=delta.y; } // --------------------------------------- // // --------------------------------------- this.add=function(x,y) { this.x+=x; this.y+=y; } // --------------------------------------- // // --------------------------------------- this.sub=function(delta) { this.x-=delta.x; this.y-=delta.y; } // --------------------------------------- // // --------------------------------------- this.set=function set(x,y) { this.x=x; this.y=y; } } // --------------------------------------- // System // --------------------------------------- function System() { // --------------------------------------- // // --------------------------------------- var lineCount=0; var consoleText=""; this.out=function(status) { lineCount++; consoleText="["+lineCount+"] "+status+"
"+consoleText; var element=document.getElementById("console"); if (element!=undefined) element.innerHTML=consoleText; } this.getWindowSize=function() { var windowSize=new Vector(0,0); if (self.innerHeight) // all except Explorer { windowSize.set(parseInt(self.innerWidth),parseInt(self.innerHeight)); } else if (document.documentElement && document.documentElement.clientHeight) // Explorer 6 Strict Mode { windowSize.set(parseInt(document.documentElement.clientWidth),parseInt(document.documentElement.clientHeight)); } else if (document.body) // other Explorers { windowSize.set(parseInt(document.body.clientWidth),parseInt(document.body.clientHeight)); } return windowSize; } } var System=new System(); // --------------------------------------- // ExtString // --------------------------------------- function ExtString() { // --------------------------------------- // notEmpty // --------------------------------------- this.notEmpty=function(val) { return (val!=null && val.lenght>0); } } var ExtString=new ExtString(); // --------------------------------------- // Request // --------------------------------------- Request=function(url,data,resultHandler) { this.url=url; this.data=data; this.resultHandler=resultHandler; } // --------------------------------------- // HttpRequestHandler // --------------------------------------- function HttpRequestHandler() { var httpRequestHandler=this; var queue=new Queue(); var httpRequestAsyn; // --------------------------------------- // // --------------------------------------- this.load=function(request) { var httpRequestSync=new ExtXMLHttpRequest(); httpRequestSync.open("POST", request.url, false); httpRequestSync.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); httpRequestSync.send(null); onLoad(request); return httpRequestSync.getResponseText(); } // --------------------------------------- // // --------------------------------------- this.loadAsync=function(request) { if (httpRequestAsyn==undefined || httpRequestAsyn.isCompleted()) { httpRequestAsyn=new ExtXMLHttpRequest(); httpRequestAsyn.setEventHandler(function(){onStateChange(request);}); httpRequestAsyn.open("POST", request.url, true); httpRequestAsyn.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); httpRequestAsyn.send(null); } else { queue.offer(request); } } // --------------------------------------- // onStateChange // --------------------------------------- function onStateChange(request) { if (httpRequestAsyn.isCompleted() && httpRequestAsyn.isStatusOk()) { request.result=httpRequestAsyn.getResponseText(); request.resultHandler.onLoad(request); if (!queue.isEmpty()) { var request=queue.poll(); httpRequestHandler.loadAsync(request); } } } // --------------------------------------- // ExtXMLHttpRequest // Extends XMLHttpRequest // --------------------------------------- function ExtXMLHttpRequest() { var httpRequest; // Constructor if (window.XMLHttpRequest) { httpRequest = new XMLHttpRequest(); if (httpRequest.overrideMimeType) { httpRequest.overrideMimeType('text/html'); } } else if (window.ActiveXObject) { try { httpRequest=new ActiveXObject("MSXML2.XMLHTTP"); } catch(MSXML2Exception) { httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); } } // Methods this.setEventHandler=function(eventHandler) { httpRequest.onreadystatechange=eventHandler; } this.open=function() { httpRequest.open(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]); } this.setRequestHeader=function() { httpRequest.setRequestHeader(arguments[0],arguments[1]); } this.send=function() { httpRequest.send(arguments[0]); } this.getResponseText=function() { return httpRequest.responseText; } this.isUninitialized=function() { return httpRequest.readyState == 0; } this.isLoading=function() { return httpRequest.readyState == 1; } this.isLoaded=function() { return httpRequest.readyState == 2; } this.isInteractive=function() { return httpRequest.readyState == 3; } this.isCompleted=function() { return httpRequest.readyState == 4; } this.isStatusOk=function() { return (httpRequest.status == 200 || httpRequest.status==0); } } // --------------------------------------- // Queue // --------------------------------------- function Queue() { var list=new Array(); this.offer=function(request) { list.push(request); } this.poll=function() { return list.shift(); } this.isEmpty=function() { return list.length==0; } } } // --------------------------------------- // Server // --------------------------------------- function Server() { httpRequestHandler=new HttpRequestHandler; // --------------------------------------- // // --------------------------------------- this.load=function(url,data) { return httpRequestHandler.load(new Request(url)); } // --------------------------------------- // // --------------------------------------- this.loadAsync=function(url) { return new this.LoadAsyncHandler(url); } // --------------------------------------- // LoadAsyncHandler // --------------------------------------- this.LoadAsyncHandler=function(url) { this.request=new Request(url); this.loadAsync=function(resultHandler,data) { this.request.resultHandler=resultHandler; this.request.data=data; httpRequestHandler.loadAsync(this.request); } } } var Server=new Server(); // --------------------------------------- // ImageBuffer // --------------------------------------- function ImageBuffer(xSize,ySize) { var base64Code="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var imageColorsBase64; // size x must be rounded to 4 bytes var size=new Vector(xSize,ySize); var fileSize=size.x*4*size.y+54; var imageHeaderBase64=bytesToBase64(new Array(66,77,fileSize & 255 ,(fileSize >> 8) & 255, (fileSize >> 16) & 255 , (fileSize >> 24) & 255 ,0,0,0,0,54,0,0,0,40,0,0,0,size.x,0,0,0,size.y,0,0,0,1,0,24,0,0,0,0,0,0,0,0,0,18,11,0,0,18,11,0,0,0,0,0,0,0,0,0,0)); this.initImage=function() { imageColorsBase64=""; for (pos=0;pos=0) && (y>=0)) { var pos=(x+y*size.x)*4; var colorBase64=bytesToBase64(new Array(b,g,r)); imageColorsBase64=imageColorsBase64.substring(0,pos)+colorBase64+imageColorsBase64.substring(pos+4,imageColorsBase64.length); } } this.drawRect=function(x1,y1,x2,y2,r,g,b) { x1=parseInt(x1); y1=parseInt(y1); x2=parseInt(x2); y2=parseInt(y2); // reverse y y1=size.y-1-y1; y2=size.y-1-y2; ya=y1;y1=y2;y2=ya; // inside image if ((x2>=0) && (y2>=0) && (x1=size.x) x2=size.x-1; if (y2>=size.y) y2=size.y-1; var rectSize=new Vector(x2-x1+1,y2-y1+1); var colorBase64=bytesToBase64(new Array(b,g,r)); var rowColorsBase64=""; for (x=x1;x<=x2;x++) rowColorsBase64+=colorBase64; var lastPos=0; var newImageColorsBase64=""; for (y=y1;y<=y2;y++) { var pos=(x1+y*size.x)*4; newImageColorsBase64+=imageColorsBase64.substring(lastPos,pos)+rowColorsBase64; lastPos=pos+rectSize.x*4; } imageColorsBase64=newImageColorsBase64+imageColorsBase64.substring(lastPos,imageColorsBase64.length); } } this.getImageSrc=function() { return "data:image;base64,"+imageHeaderBase64+imageColorsBase64 } function bytesToBase64(byteData) { var bitData=0; var bitCount=0; var b64Data=new Array(); for (pos=0;pos=6 || (bitCount>0 && pos==byteData.length-1)) { var bitData6=bitData >> (bitCount-6); bitData=bitData % (1 << (bitCount-6)); b64Data+=base64Code[bitData6]; bitCount-=6; } } return b64Data; } } // --------------------------------------- // Animator // --------------------------------------- function Animator() { var fps=30; var sequences=new Array(); // --------------------------------------- // // --------------------------------------- this.getFps=function() { return fps; } // --------------------------------------- // // --------------------------------------- this.timerEvent=function() { var currentTime=new Date().getTime(); var newSequences=new Array(); var slength=sequences.length; //System.out("slength="+slength); for (sequenceNo=0;sequenceNo=0 && a<1.0) { sequence.seqFunction(a,sequence.data); newSequences.push(sequence); } else if (a>=1.0) { a=1.0; sequence.seqFunction(a,sequence.data); } else { newSequences.push(sequence); } } } sequences=newSequences; setTimeout(Animator.timerEvent,1000/fps); } // --------------------------------------- // // --------------------------------------- this.addSequence=function(startTime,endTime,seqFunction,data) { var currentTime=new Date().getTime(); if (startTime!=null) startTime+=currentTime; if (endTime!=null) endTime+=currentTime; sequences.push(new Sequence(seqFunction,startTime,endTime,data)); } // --------------------------------------- // Sequence // --------------------------------------- Sequence=function(seqFunction,startTime,endTime,data) { this.seqFunction=seqFunction; this.startTime=startTime this.endTime=endTime; this.data=data; } var startTime=new Date().getTime(); setTimeout(this.timerEvent,1000/fps); } var Animator=new Animator(); // --------------------------------------- // Element // with load // functionalities // --------------------------------------- function Element() { // --------------------------------------- // getSize // --------------------------------------- this.getSize=function(element) { if (typeof element=="string") element=document.getElementById(element); return new Vector(parseInt(element.offsetWidth),parseInt(element.offsetHeight)); } // --------------------------------------- // getScrollPosition // --------------------------------------- this.getScrollPosition=function(element) { if (typeof element=="string") element=document.getElementById(element); return new Vector(parseInt(element.scrollLeft),parseInt(element.scrollTop)); } // --------------------------------------- // getPositionToParent // --------------------------------------- this.getPositionToParent=function(element,parentElement) { if (typeof element=="string") element=document.getElementById(element); if (typeof parentElement=="string") parentElement=document.getElementById(parentElement); var position = new Vector(0,0); { do { position.x += parseInt(element.offsetLeft); position.y += parseInt(element.offsetTop); element = element.offsetParent; } while (element.offsetParent && element!=parentElement); } return position; } // --------------------------------------- // setHTML // --------------------------------------- this.setHTML=function(element,obj) { if (typeof element=="string") element=document.getElementById(element); this.element=element; if (obj instanceof Server.LoadAsyncHandler) { obj.loadAsync(this,this.element); } else { this.element.innerHTML=obj; } // --------------------------------------- // onLoad // --------------------------------------- this.onLoad=function(request) { contentFade(request); //var element=request.data; //element.innerHTML=request.result; onLoad(request); } } } var Element=new Element(); // --------------------------------------- // ExtendedEventHandler // --------------------------------------- function ExtendedEventHandler() { // --------------------------------------- // checkEvents // --------------------------------------- this.checkEvents=function() { var elements=document.getElementsByTagName("div"); for (elementNo=0;elementNoviewportPosition.x && elementPosition.yviewportPosition.y); } } var ExtEventHandler=new ExtendedEventHandler(); // --------------------------------------- // main // --------------------------------------- // --------------------------------------- // // --------------------------------------- function onStart() { _uacct = 'UA-890809-1'; urchinTracker(); preload=new Image(); preload.src="/images/loading.gif"; Element.setHTML("ui",Server.load("/content-ui.php")); Element.setHTML("contents",Server.load("/content-contents.php")); // set focus to viewport so user can user cursor-keys to scroll document.getElementById("viewport").focus(); setPadPos(); ExtEventHandler.checkEvents(); } // --------------------------------------- // // --------------------------------------- function onEnd() { _uacct = 'UA-890809-1'; urchinTracker(); } // --------------------------------------- // // --------------------------------------- function onLoad(request) { System.out("loaded("+request.url+")"); ExtEventHandler.checkEvents(); } // --------------------------------------- // // --------------------------------------- function onScroll() { setPadPos(); ExtEventHandler.checkEvents(); } // --------------------------------------- // // --------------------------------------- window.onresize = onResize; function onResize() { setPadPos(); ExtEventHandler.checkEvents(); } // --------------------------------------- // contentFadeIn // --------------------------------------- this.contentFadeIn=function(a,data) { a*=a; var element=data.data; element.style.opacity=a; element.style.filter="alpha(opacity="+Math.round(a*100)+")"; if (a==1.0) { /*if (element.childNodes.length>0) alert("element.childNodes[0]="+element.childNodes[0]);*/ element.style.filter=""; element.style.opacity=""; ExtEventHandler.checkEvents(); } } // --------------------------------------- // contentFadeOut // --------------------------------------- this.contentFadeOut=function(a,data) { var element=data.data; element.style.opacity=1-a; element.style.filter="alpha(opacity="+Math.round(100-a*100)+")"; } // --------------------------------------- // contentFadeOut // --------------------------------------- this.contentChange=function(a,data) { var element=data.data; element.style.opacity=0; element.style.filter="alpha(opacity=0)"; element.innerHTML=data.result; } // --------------------------------------- // contentFade // --------------------------------------- function contentFade(data) { System.out(data.data.id); Animator.addSequence(0,400,contentFadeOut,data); Animator.addSequence(500,600,contentChange,data); Animator.addSequence(700,3000,contentFadeIn,data); } // --------------------------------------- // // --------------------------------------- /*function scrollToContent(id) { var pos=Element.getPositionToParent(id,"viewport"); document.getElementById('viewport').scrollLeft=pos.x-128; document.getElementById('viewport').scrollTop=pos.y-128; }*/ // --------------------------------------- // // --------------------------------------- function scrollToContent(id) { var startPos=new Vector(document.getElementById('viewport').scrollLeft,document.getElementById('viewport').scrollTop); var endPos=Element.getPositionToParent(id,"viewport"); endPos.x-=128; endPos.y-=128; var dx=Math.abs(endPos.x-startPos.x); var dy=Math.abs(endPos.y-startPos.y); var d=dx+dy; /*if (dx>dy) { var medPos=new Vector(endPos.x,startPos.y); Animator.addSequence(0,2000*dx/d+500,setScrollPosition,new Array(startPos, medPos)); Animator.addSequence(2000*dx/d+500,3000,setScrollPosition,new Array(medPos, endPos)); } else { var medPos=new Vector(startPos.x,endPos.y); Animator.addSequence(0,2000*dy/d+500,setScrollPosition,new Array(startPos, medPos)); Animator.addSequence(2000*dy/d+500,3000,setScrollPosition,new Array(medPos, endPos)); }*/ var slow=2; if (dx>dy) { dx+=250; d+=500; var medPos=new Vector(endPos.x,startPos.y); Animator.addSequence(0,dx*slow,setScrollPosition,new Array(startPos, medPos)); // avoid scrolling small parts, when content is aways visible if (dy<0 || dy>32) Animator.addSequence(dx*slow,d*slow,setScrollPosition,new Array(medPos, endPos)); } else { dy+=250; d+=500; var medPos=new Vector(startPos.x,endPos.y); Animator.addSequence(0,dy*slow,setScrollPosition,new Array(startPos, medPos)); // avoid scrolling small parts, when content is aways visible if (dx<0 || dx>32) Animator.addSequence(dy*slow,d*slow,setScrollPosition,new Array(medPos, endPos)); } } function setScrollPosition(a,data) { var b=(1.0-Math.cos(a*Math.PI))/2.0; var element=document.getElementById('viewport'); var x=parseInt(data[0].x*(1.0-b)+data[1].x*b); var y=parseInt(data[0].y*(1.0-b)+data[1].y*b); element.scrollLeft=x; element.scrollTop=y; } // --------------------------------------- // // --------------------------------------- this.scrollViewport=function() { var speed=1000; scrollVector.x=(scrollAccel.x); scrollVector.y=(scrollAccel.y); var scrollPosNew=new Vector(scrollPos.x+scrollVector.x*speed/30,scrollPos.y+scrollVector.y*speed/30); var dx=Math.round(scrollPosNew.x)-Math.round(scrollPos.x); var dy=Math.round(scrollPosNew.y)-Math.round(scrollPos.y); //System.out(""+scrollVector.y); document.getElementById('viewport').scrollLeft+=dx; document.getElementById('viewport').scrollTop+=dy; scrollPos=scrollPosNew; if (scrollTimer!=0) setTimeout(this.scrollViewport,1000/Animator.getFps()); } // --------------------------------------- // // --------------------------------------- function doScrollViewport(direction) { scrollAccel=direction; scrollTimer=setTimeout(this.scrollViewport,1000/Animator.getFps()); } // --------------------------------------- // // --------------------------------------- function stopScrollViewport() { scrollTimer=0; scrollAccel.set(0,0); } var scrollVector=new Vector(0,0); var scrollAccel=new Vector(0,0); var scrollPos=new Vector(0,0); var scrollTimer=0; // --------------------------------------- // // --------------------------------------- function imagePaneFadeOut(a,element) { element.style.opacity=(1-a); element.style.filter="alpha(opacity="+Math.round((100-a*100))+")"; if (a==1.0) { element.style.display = 'none'; } } function imagePaneFadeIn(a,element) { element.style.opacity=a; element.style.filter="alpha(opacity="+Math.round(a*100)+")"; element.style.display = 'block'; } function closeImagePaneEvent() { Animator.addSequence(0,750,imagePaneFadeOut,document.getElementById('imagePane')) } function openImagePaneEvent(image) { var imageElement=document.getElementById('showImage'); imageElement.src="/images/loading.gif"; Animator.addSequence(0,1000,imagePaneFadeIn,document.getElementById('imagePane')) imageElement.src=image; } // --------------------------------------- // Pad // --------------------------------------- var isPadScrolling=false; document.onmousemove = mouseMove; document.onmousedown = mouseDown; var padImage=new ImageBuffer(136,136); function mouseDown(evt) { if (isPadScrolling) { return false; } } function doPadScrollPlane(evt) { isPadScrolling=true; mouseMove(evt); } function stopPadScrollPlane(evt) { isPadScrolling=false; } function mouseMove(evt) { evt=ensureEvent(evt); if (isPadScrolling) { var viewportElement=document.getElementById('viewport'); var contentsElement=document.getElementById('contents'); var scrollPadElement=document.getElementById('scrollPad'); var scrollPadPosElement=document.getElementById('scrollPadPos'); var mousePos=new Vector(evt.clientX,evt.clientY); var viewportPos=new Vector(viewportElement.scrollLeft,viewportElement.scrollTop); var contentsSize=new Vector(contentsElement.offsetWidth,contentsElement.offsetHeight); /* var scrollPadPos=new Vector(scrollPadElement.offsetLeft,scrollPadElement.offsetTop); */ var scrollPadPos=Element.getPositionToParent("scrollPad","viewport"); var scrollPadSize=new Vector(scrollPadElement.offsetWidth,scrollPadElement.offsetHeight); //var windowSize=System.getWindowSize(); var windowSize=new Vector(viewportElement.offsetWidth-25,viewportElement.offsetHeight-25); windowSize.x-=25; windowSize.y-=25; /*alert(scrollPadPos.x+" "+scrollPadPos.y);*/ var border=7; scrollPadSize.x-=border*2; scrollPadSize.y-=border*2; scrollPadPos.x+=border; scrollPadPos.y+=border; var padRx=(mousePos.x-scrollPadPos.x)/(scrollPadSize.x); var padRy=(mousePos.y-scrollPadPos.y)/(scrollPadSize.y); if (padRx>1.0) padRx=1.0; if (padRy>1.0) padRy=1.0; if (padRx<0.0) padRx=0.0; if (padRy<0.0) padRy=0.0; viewportElement.scrollLeft=padRx * (contentsSize.x-windowSize.x); viewportElement.scrollTop=padRy * (contentsSize.y-windowSize.y); setPadPos(); return false; } } function setPadPos() { var viewportElement=document.getElementById('viewport'); var contentsElement=document.getElementById('contents'); var scrollPadElement=document.getElementById('scrollPad'); var scrollPadPosElement=document.getElementById('scrollPadPos'); var contentsSize=new Vector(contentsElement.offsetWidth,contentsElement.offsetHeight); //var windowSize=System.getWindowSize(); var windowSize=new Vector(viewportElement.offsetWidth-25,viewportElement.offsetHeight-25); windowSize.x-=25; windowSize.y-=25; var scrollPadSize=new Vector(scrollPadElement.offsetWidth,scrollPadElement.offsetHeight); var border=0; scrollPadSize.x-=border*2; scrollPadSize.y-=border*2; var padSize=new Vector(parseInt(scrollPadSize.x*windowSize.x/contentsSize.x), parseInt(scrollPadSize.y*windowSize.y/contentsSize.y)); var padPos=new Vector(parseInt(viewportElement.scrollLeft*(scrollPadSize.x-padSize.x)/(contentsSize.x-windowSize.x)), parseInt(viewportElement.scrollTop*(scrollPadSize.y-padSize.y)/(contentsSize.y-windowSize.y))); // firefox only, because ie7 does not support base64 decoding if ((navigator.appName == 'Netscape') && (navigator.userAgent.indexOf('Firefox')!=-1)) { padImage.drawRect(padPos.x,padPos.y, padPos.x+padSize.x, padPos.y+padSize.y,255,0,0); document.getElementById("padImage").src=padImage.getImageSrc(); } scrollPadPosElement.style.width=padSize.x; scrollPadPosElement.style.height=padSize.y; scrollPadPosElement.style.left=padPos.x+7; scrollPadPosElement.style.top=padPos.y+7; } function ensureEvent(evt) { if (!evt) evt = window.event; return evt; } // --------------------------------------- // imageFadeIn // --------------------------------------- this.imageFadeIn=function(a,element) { element.style.opacity=a; element.style.filter="alpha(opacity="+Math.round(a*100)+")"; } // --------------------------------------- // imageFade // --------------------------------------- function doImageFadeIn(element) { Animator.addSequence(0,1000,imageFadeIn,element); }