//=============================================== javascript Library last update: 05/11/2009
//making by www.dtop.jp
//=============================================================================== 基本設定
//將瀏覽器判別結果存放至全域變數
var _MSIE = (navigator.userAgent.indexOf('MSIE') != -1);		//Windows IE（支援瀏覽器為IE6以上）
var _Gecko = (navigator.userAgent.indexOf('Gecko') != -1);		//Firefox
var _Safari = (navigator.userAgent.indexOf('Safari') != -1);	//Safari

//window相關函式---------------------------------------------------------------
//window的寬度
//參數：
//回傳值：window的寬度
function windowWidth(){
	if(_MSIE){
		return document.documentElement.clientWidth;
	}
	else{
		return window.innerWidth;
	}
}

//window的高度
//參數：
//回傳值：window的高度
function windowHeight(){
	if(_MSIE){
		return document.documentElement.clientHeight;
	}
	else{
		return window.innerHeight;
	}
}

//==================================================== 設定建構子與 prototype
//Effect物件與建構式
//參數：emID:元素id　et：花費時間　k：變化的種類
function Effect(emID,et,k){
	this.element = document.getElementById(emID);	//元素名稱
	this.endtime = et;								//花費時間
	this.kind = k;									//變化的種類
	this.starttime = 0;								//起始時間
}
//prototype屬性的設定-------------------------------------------------
//影格速率的設定
Effect.prototype.fps = 1000/30;

//取得元素X,Y位置，建立X,Y屬性
//參數：
//回傳值：建立prototype屬性 存放（x,y）
Effect.prototype.elementXY_Init = function(){
	this.x = this.element.offsetLeft;
	this.y = this.element.offsetTop;
}

//取得元素寬度、高度，建立w,h屬性
//參數：
//回傳值：建立prototype屬性 存放（w,h）
Effect.prototype.zoom_Init = function(){
	this.w = this.element.clientWidth;
	this.h = this.element.clientHeight;
}

//取得元素目前寬度、高度，建立w,h屬性
//參數：
//回傳值：建立prototype屬性存放（w,h）
Effect.prototype.nowWH_Init = function(){
	this.nowW = this.element.clientWidth;
	this.nowH = this.element.clientHeight;
}

//取得元素視窗的中心座標，確定元素中央位置後，求得左上角的實際x,y
//參數：
//回傳值：建立prototype屬性 存放（x,y）
Effect.prototype.center_Set = function(){
	var wW = windowWidth();
	var wH = windowHeight();
	var sx;
	var sy;
	
	if(_MSIE){
		sx = document.documentElement.scrollLeft;
		sy = document.documentElement.scrollTop;
	}
	else{
		sx = window.pageXOffset;
		sy = window.pageYOffset;
	}
	this.x = wW/2+sx-this.nowW/2;
	this.y = wH/2+sy-this.nowH/2;
}

//取得元素.opacity，建立 alp 屬性
//參數：
//回傳值：建立prototype屬性（alp）存放(0-100%)
Effect.prototype.alpha_Init = function(){
	if(_MSIE){
		this.alp = parseInt( (this.element.currentStyle.filter).match(/\d+/) );
	}
	else{
		this.alp = parseFloat(document.defaultView.getComputedStyle(this.element, null).getPropertyValue('opacity'))*100;
	}
}


//prototype方法的設定-------------------------------------------------
//變更元素位置
//參數：x:X座標　y:Y座標
//回傳值：
Effect.prototype.elementXY_Set = function(x,y){
	this.element.style.left = x+"px";
	this.element.style.top  = y+"px";
}

//元素的透明度
//參數：alp:透明度(0-100%)
//回傳值：
Effect.prototype.alpha_Set = function(alp){
	if(_MSIE){
		this.element.style.filter = 'alpha(opacity='+alp+')';
	}
	else{
		this.element.style.opacity = alp/100;
	}
}

//元素縮放函式（等比例）
//參數：z:放大比例(0-100%)
//回傳值：
Effect.prototype.zoom_Set = function(z){
	this.element.style.width = (this.w*z/100) + 'px';
	this.element.style.height = (this.h*z/100) + 'px';
}

//顯示／隱藏元素函式
//參數：v:隱藏/顯示(0/1)
//回傳值：
Effect.prototype.visible_Set = function(v){
	if(v == 0) this.element.style.visibility = "hidden";
	else this.element.style.visibility = "visible";
}


//設定prototype方法中的動作變化----------------------------------
//變化種類的選擇器
//參數：v 與目標值的差　f 花費frame　sv 起始的值　nowf 目前的frame
//k 變化種類
//up:徐徐減速
//down:徐徐加速
//same:等速
//updawn:徐徐加速再減速

//回傳值：求取目前的v
Effect.prototype.CHANGE = function(k,v,f,sv,nowf){
	switch(k){
		case 'up':
			return this.UP(v,f,sv,nowf);
			break;
		case 'down':
			return this.DOWN(v,f,sv,nowf);
			break;
		case 'same':
			return this.SAME(v,f,sv,nowf);
			break;
		case 'updown':
			return this.UPDOWN(v,f,sv,nowf);
			break;
	}
}


//徐徐減速
//參數：v 與目標值的差　f 花費frame　sv 起始的值　nowf 目前的frame
//回傳值：求取目前的v
Effect.prototype.UP = function(v,f,sv,nowf){
	return sv+( v/Math.sqrt(f)*Math.sqrt(nowf) );
}

//徐徐加速
//參數：v:與目標值的差　f:花費frame　sv:起始的值　nowf:目前的frame
//回傳值：求取目前的v
Effect.prototype.DOWN = function(v,f,sv,nowf){
	return sv+( v/(f*f)*(nowf*nowf) );
}

//等速
//參數：v:與目標值的差　f:花費frame　sv:起始的值　nowf:目前的frame
//回傳值：求取目前的v
Effect.prototype.SAME = function(v,f,sv,nowf){
	return sv+( v/f*nowf );
}

//徐徐加速再減速
//參數：v:與目標值的差　f:花費frame　sv:起始的值　nowf:目前的frame
//回傳值：求取目前的v
Effect.prototype.UPDOWN = function(v,f,sv,nowf){
	var v1 = Math.floor(v/2);
	var v2 = v-v1;
	var fr1 = Math.floor(f/2);
	var fr2 = f-fr1;
	
	if(fr1 >= nowf){
		return sv+( v1/(fr1*fr1)*(nowf*nowf) );
	}
	else{
		if(v != 0) sv = sv+v1;
			return sv+( v2/Math.sqrt(fr2)*Math.sqrt(nowf-fr1) );
	}
}


//主要的prototype方法======================================================
//迴圈本身
Effect.prototype.LOOP = function(){
	this.starttime++;
	this.MAIN();	//可新增變更（視覺效果變更）
	if(this.starttime >= this.endtime){
		clearInterval(this.settimer);
		if(this.endevent) this.END();	//結束後執行的事件（視覺效果變更）
	}
}

//主要執行（宣告這個部份迴圈就開始了）
Effect.prototype.START = function(){
	var myObj = this;
	this.settimer = setInterval(function(){myObj.LOOP()},myObj.fps);
}


//====================================================================== 效果函式的設定
//變更透明度
//參數：emID:元素名稱　alp:變更後的 alpha(0-100)　t:花費時間　k:變化的種類
//endev:動作結束後呼叫的物件（需要next_Event()方法）
function alpha(emID,alp,t,k,endev){
	var obj = new Effect(emID,t,k);

	//取得目前透明度與建立屬性
	obj.alpha_Init();
	obj.endevent = endev;
	
	//在Effect建構式中加入屬性
	obj.ealp = alp;
	
	//主方法
	obj.MAIN = function(){
		var ALP = this.CHANGE(this.kind,(this.ealp-this.alp),this.endtime,this.alp,this.starttime);
		this.alpha_Set(ALP);
	}
	//結束後呼叫的方法
	obj.END = function(){
		endev.next_Event();
	}
	
	//動作開始
	obj.START();
}

//放大縮小
//參數：emID:元素名稱　z:變更後的放大比例(0-100)　t:花費時間　k:變化的種類
//endev:動作結束後呼叫的事件（需要next_Event()方法）
function zoom(emID,z,t,k,endev){
	var obj = new Effect(emID,t,k);

	//取的目前大小與建立屬性
	obj.elementXY_Init();
	obj.zoom_Init();
	obj.endevent = endev;

	//在Effect建構式中加入屬性
	obj.zoom = z;
	
	//主方法
	obj.MAIN = function(){
		var ZOOM = this.CHANGE(this.kind,(this.zoom-100),this.endtime,100,this.starttime);
		this.zoom_Set(ZOOM);
		this.nowWH_Init();
		this.center_Set();
		
		//超出視窗顯示位置時設為0
		if(this.x<0) this.x = 0;
		if(this.y<0) this.y = 0;
		
		this.elementXY_Set(this.x, this.y);
	}
	//結束後呼叫的方法
	obj.END = function(){
		endev.next_Event();
	}

	//動作開始
	obj.START();
}


