DIR : /home/kozerus/public_html/jkwii/js/jsdoit/graphpape/index.jsx

/home/kozerus/public_html/jkwii/js/jsdoit/graphpape

import 'js.jsx';
import 'js/web.jsx';
import 'timer.jsx';

// ----------------------------------------------------------------
// ----------------------------------------------------------------
// ----------------------------------------------------------------

// メインクラス
class _Main{
	// ----------------------------------------------------------------
	// main関数
	static function main(args : string[]) : void{
		Ctrl.init();
		// ループ開始
		_Main.mainloop();
	}

	// ----------------------------------------------------------------
	// mainloop関数
	static function mainloop() : void{
		Ctrl.calc();
		Ctrl.draw();
/*
		// グリッド
		Ctrl.sctx.strokeStyle = "gray";
		for(var i = 10; i < 240; i += 10){
			Ctrl.sctx.beginPath();
			Ctrl.sctx.moveTo(i, 0);
			Ctrl.sctx.lineTo(i, 160);
			Ctrl.sctx.stroke();
		}
		for(var i = 10; i < 160; i += 10){
			Ctrl.sctx.beginPath();
			Ctrl.sctx.moveTo(0, i);
			Ctrl.sctx.lineTo(240, i);
			Ctrl.sctx.stroke();
		}
//*/
		Ctrl.sctx.strokeStyle = "black";
		// ベルトコンベア
		_Main.drawConveyor(20, 100, 120, 20, 5);
		// プレス
		Ctrl.sctx.strokeRect(100, 10 + 40 * Ctrl.lPower, 50, 50);


		// 次のフレームへ
		Timer.setTimeout(_Main.mainloop, 33);
	}

	// ----------------------------------------------------------------
	// ベルトコンベア描画
	static function drawConveyor(x : number, y : number, l : number, r : number, d : number) : void{
		var f = function(t : number) : number[]{
			var r2 = r * Math.PI;
			while(t > 1){t -= 1;}
			while(t < 0){t += 1;}
			var p0 : number = t * (l + r2) * 2;
			var p1 : number = p0 - l;
			var p2 : number = p1 - r2;
			var p3 : number = p2 - l;
			var p4 : number = p3 - r2;
			if(p1 < 0){
				var x0 = x + r + p0;
				var y0 = y;
				return [x0, y0, x0, y0 + d];
			}else if(p2 < 0){
				var x0 = x + r + l;
				var y0 = y + r;
				var t = Math.PI * p1 / r2;
				var s =  Math.sin(t);
				var c = -Math.cos(t);
				return [x0 + r * s, y0 + r * c, x0 + (r - d) * s, y0 + (r - d) * c];
			}else if(p3 < 0){
				var x0 = x + r + l - p2;
				var y0 = y + r + r;
				return [x0, y0, x0, y0 - d];
			}else if(p4 < 0){
				var x0 = x + r;
				var y0 = y + r;
				var t = Math.PI * p3 / r2;
				var s = -Math.sin(t);
				var c =  Math.cos(t);
				return [x0 + r * s, y0 + r * c, x0 + (r - d) * s, y0 + (r - d) * c];
			}else{
				var x0 = x + r + p4;
				var y0 = y;
				return [x0, y0, x0, y0 + d];
			}
		};
		for(var i = 0; i < 20; i++){
			Ctrl.sctx.beginPath();
			var p0 = f((i + 0.0 + 0.3 * Ctrl.hPower) / 20);
			var p1 = f((i + 0.8 + 0.3 * Ctrl.hPower) / 20);
			Ctrl.sctx.beginPath();
			Ctrl.sctx.moveTo(p0[2], p0[3]);
			Ctrl.sctx.lineTo(p0[0], p0[1]);
			Ctrl.sctx.lineTo(p1[0], p1[1]);
			Ctrl.sctx.lineTo(p1[2], p1[3]);
			Ctrl.sctx.closePath();
			Ctrl.sctx.stroke();
		}
	}
}

// ----------------------------------------------------------------
// ----------------------------------------------------------------
// ----------------------------------------------------------------

// コントローラクラス
class Ctrl{
	static var wbox = new Ctrl.Box(0, 0, 0, 0);
	static var sbox = new Ctrl.Box(0, 0, 240, 160);
	static var cbox = new Ctrl.Box(0, 0, 160, 240);
	// キャンバス要素
	static var scvs : HTMLCanvasElement;
	static var ccvs : HTMLCanvasElement;
	static var sctx : CanvasRenderingContext2D;
	static var cctx : CanvasRenderingContext2D;
	// タッチ状態
	static var isTouch : boolean;
	static var tdn : boolean;
	static var tmv : boolean;
	static var tx : int = 0;
	static var ty : int = 0;
	static var _temptx : int;
	static var _tempty : int;
	static var _info = new Ctrl._TouchInfo[];
	// ボタン押下範囲
	static var lHitBox = new Ctrl.Box(10, -10, 80, 60);
	static var hHitBox = new Ctrl.Box(20, 120, 120, 120);
	// レバー情報
	static var lGrab = false;
	static var lPower : number = 0.0;
	// ハンドル情報
	static var hx : number = 0;
	static var hy : number = 0;
	static var hPower : number = 0.0;
	static var hRot : number = 0.0;

	// ----------------------------------------------------------------
	// 初期化
	static function init() : void{
		var div = dom.document.getElementById("ctrl") as HTMLDivElement;
		Ctrl.scvs = dom.document.getElementById("screen") as HTMLCanvasElement;
		Ctrl.ccvs = dom.document.getElementById("ctrler") as HTMLCanvasElement;
		Ctrl.sctx = Ctrl.scvs.getContext("2d") as CanvasRenderingContext2D;
		Ctrl.cctx = Ctrl.ccvs.getContext("2d") as CanvasRenderingContext2D;
		// リスナー追加
		Ctrl.isTouch = js.eval("'ontouchstart' in window") as boolean;
		if(Ctrl.isTouch){
			div.addEventListener("touchstart", Ctrl._tdnfn);
			div.addEventListener("touchmove", Ctrl._tmvfn);
			div.addEventListener("touchend", Ctrl._tupfn);
			div.addEventListener("touchcancel", Ctrl._tupfn);
		}else{
			div.addEventListener("mousedown", Ctrl._tdnfn);
			div.addEventListener("mousemove", Ctrl._tmvfn);
			div.addEventListener("mouseup", Ctrl._tupfn);
			div.addEventListener("mouseout", function(e : Event) : void{
				var x = (e as MouseEvent).clientX;
				var y = (e as MouseEvent).clientY;
				if(x <= 0 || Ctrl.wbox.w <= x || y <= 0 || Ctrl.wbox.h <= y){
					Ctrl._tupfn(e);
				}
			});
		}
	}

	// ----------------------------------------------------------------
	// 計算
	static function calc() : void{
		var ww = dom.window.innerWidth;
		var wh = dom.window.innerHeight;
		if(Ctrl.wbox.w != ww || Ctrl.wbox.h != wh){
			Ctrl.wbox.w = ww;
			Ctrl.wbox.h = wh;
			var scvs = dom.document.getElementById("screen") as HTMLCanvasElement;
			var ccvs = dom.document.getElementById("ctrler") as HTMLCanvasElement;
			if(ww > wh){
				var wgap = Math.floor((Ctrl.wbox.w - Ctrl.sbox.w - Ctrl.cbox.w) / 3);
				Ctrl.sbox.x = wgap;
				Ctrl.cbox.x = wgap + Ctrl.sbox.w + wgap;
				Ctrl.sbox.y = Math.floor((Ctrl.wbox.h - Ctrl.sbox.h) / 2);
				Ctrl.cbox.y = Math.floor((Ctrl.wbox.h - Ctrl.cbox.h) / 2);
			}else{
				var hgap = Math.floor((Ctrl.wbox.h - Ctrl.sbox.h - Ctrl.cbox.h) / 3);
				Ctrl.sbox.x = Math.floor((Ctrl.wbox.w - Ctrl.sbox.w) / 2);
				Ctrl.cbox.x = Math.floor((Ctrl.wbox.w - Ctrl.cbox.w) / 2);
				Ctrl.sbox.y = hgap;
				Ctrl.cbox.y = hgap + Ctrl.sbox.h + hgap;
			}
			scvs.style.left = (Ctrl.sbox.x as string) + "px";
			ccvs.style.left = (Ctrl.cbox.x as string) + "px";
			scvs.style.top = (Ctrl.sbox.y as string) + "px";
			ccvs.style.top = (Ctrl.cbox.y as string) + "px";
		}

		// レバー位置復帰計算
		if(!Ctrl.lGrab){Ctrl.lPower += (0.0 - Ctrl.lPower) * 0.1;}
		// レバーあたり判定計算
		Ctrl.lHitBox.y = -10 + 90 * Ctrl.lPower;
	}

	// ----------------------------------------------------------------
	// 描画
	static function draw() : void{
		Ctrl.sctx.fillStyle = "white";
		Ctrl.sctx.fillRect(0, 0, Ctrl.scvs.width, Ctrl.scvs.height);

		Ctrl.cctx.fillStyle = "white";
		Ctrl.cctx.fillRect(0, 0, Ctrl.ccvs.width, Ctrl.ccvs.height);
//*
		// グリッド
		Ctrl.cctx.strokeStyle = "gray";
		for(var i = 10; i < 160; i += 10){
			Ctrl.cctx.beginPath();
			Ctrl.cctx.moveTo(i, 0);
			Ctrl.cctx.lineTo(i, 240);
			Ctrl.cctx.stroke();
		}
		for(var i = 10; i < 240; i += 10){
			Ctrl.cctx.beginPath();
			Ctrl.cctx.moveTo(0, i);
			Ctrl.cctx.lineTo(160, i);
			Ctrl.cctx.stroke();
		}
//*/
		// レバー
		var y0 = 50 + 30 * Ctrl.lPower; // ハンドルの根本中心
		var y1 = 20 + 90 * Ctrl.lPower; // ハンドルの取手中心
		Ctrl.cctx.fillStyle = "red";
		Ctrl.cctx.fillRect(30, 30, 40, 70);
		Ctrl.cctx.fillStyle = "pink";
		Ctrl.cctx.fillRect(40, 40, 20, 50);
		Ctrl.cctx.fillStyle = "gray";
		Ctrl.cctx.beginPath();
		Ctrl.cctx.arc(50, y0, 10, 0, Math.PI * 2, true);
		Ctrl.cctx.fill();
		Ctrl.cctx.fillRect(40, y0, 20, y1 - y0);
		Ctrl.cctx.fillStyle = "black";
		Ctrl.cctx.fillRect(10, y1 - 10, 80, 20);
		Ctrl.cctx.fillStyle = "white";
		Ctrl.cctx.fillRect(10, y1 + 5, 80, 3);

		// ハンドル
		var cos : number = Math.cos(Ctrl.hRot);
		var sin : number = Math.sin(Ctrl.hRot);
		Ctrl.cctx.fillStyle = "red";
		Ctrl.cctx.beginPath();
		Ctrl.cctx.arc(80, 180, 50, 0, Math.PI * 2, true);
		Ctrl.cctx.fill();
		Ctrl.cctx.fillStyle = "pink";
		Ctrl.cctx.beginPath();
		Ctrl.cctx.arc(80 + 30 * cos, 180 + 30 * sin, 20, 0, Math.PI * 2, true);
		Ctrl.cctx.fill();

		// ランプ
		Ctrl.cctx.fillStyle = "red";
		Ctrl.cctx.beginPath();
		Ctrl.cctx.arc(120, 40, 10, 0, Math.PI * 2, true);
		Ctrl.cctx.fill();
		Ctrl.cctx.fillStyle = "green";
		Ctrl.cctx.beginPath();
		Ctrl.cctx.arc(120, 70, 10, 0, Math.PI * 2, true);
		Ctrl.cctx.fill();
		Ctrl.cctx.fillStyle = "blue";
		Ctrl.cctx.beginPath();
		Ctrl.cctx.arc(120, 100, 10, 0, Math.PI * 2, true);
		Ctrl.cctx.fill();
	}

	// ----------------------------------------------------------------
	// タッチ位置がボックス範囲内にあるか確認
	static function _checkTouchBox(box : Ctrl.Box, tx : int, ty : int) : boolean{
		if(box == null){return false;}
		var x0 = box.x;
		var y0 = box.y;
		if(box == Ctrl.lHitBox || box == Ctrl.hHitBox){
			// コントローラ座標系
			x0 += Ctrl.cbox.x;
			y0 += Ctrl.cbox.y;
		}else{
			// 全体座標系で負数指定の場合は反対側を基準とする
			x0 = box.x >= 0 ? x0 : Ctrl.wbox.w + x0;
			y0 = box.y >= 0 ? y0 : Ctrl.wbox.h + y0;
		}
		var x1 = x0 + box.w;
		var y1 = y0 + box.h;
		return (x0 < tx && tx < x1 && y0 < ty && ty < y1);
	}

	// ----------------------------------------------------------------
	// コントローラタッチ時の処理
	static function _calcTouchButton(box : Ctrl.Box, tx : int, ty : int, dn : boolean, up : boolean) : void{
		if(box == Ctrl.lHitBox){
			// レバー操作処理
			Ctrl.lPower = Math.max(0, Math.min(1, (ty - Ctrl.cbox.y - 10) / 110));
			Ctrl.lGrab = !up;
		}else if(box == Ctrl.hHitBox){
			// ハンドル操作処理
			var x1 = tx - Ctrl.cbox.x - 80;
			var y1 = ty - Ctrl.cbox.y - 180;
			if(!dn){
				var x0 = Ctrl.hx;
				var y0 = Ctrl.hy;
				var r0 = Math.sqrt(x0 * x0 + y0 * y0);
				var r1 = Math.sqrt(x1 * x1 + y1 * y1);
				if(r0 > 20 && r1 > 20){
					var cos = Math.max(-1, Math.min(1, (x0 * x1 + y0 * y1) / (r0 * r1)));
					Ctrl.hPower += Math.acos(cos) * ((x0 * y1 - y0 * x1 > 0) ? 1 : -1);
				}
			}
			Ctrl.hx = x1;
			Ctrl.hy = y1;
			Ctrl.hRot = Math.atan2(y1, x1);
		}
	}

	// ----------------------------------------------------------------
	// タッチとマウスの処理振り分け
	static function _calcEvent(e : Event, calc : function(tx:int,ty:int,id:int):boolean) : void{
		var active = false;
		if(Ctrl.isTouch){
			var te = e as TouchEvent;
			for(var i = 0; i < te.changedTouches.length; i++){
				var touch = te.changedTouches[i];
				active = calc(touch.clientX, touch.clientY, touch.identifier) || active;
			}
		}else{
			var me = e as MouseEvent;
			active = calc(me.clientX, me.clientY, 0);
		}

		if(active){

		}
	}

	// ----------------------------------------------------------------
	// ルート要素 タッチ開始
	static function _tdnfn(e : Event) : void{
		Ctrl._calcEvent(e, function(tx : int, ty : int, id : int) : boolean{
			// タッチ範囲確認
			var box : Ctrl.Box;
			if(Ctrl._checkTouchBox(Ctrl.sbox, tx, ty)){box = Ctrl.sbox;}
			else if(Ctrl._checkTouchBox(Ctrl.lHitBox, tx, ty)){box = Ctrl.lHitBox;}
			else if(Ctrl._checkTouchBox(Ctrl.hHitBox, tx, ty)){box = Ctrl.hHitBox;}
			else{return false;}
			// マルチタッチ情報重複確認
			for(var i = 0; i < Ctrl._info.length; i++){if(box == Ctrl._info[i].box){return false;}}
			// マルチタッチ情報作成
			Ctrl._info.push(new Ctrl._TouchInfo(id, box));

			if(box == Ctrl.sbox){
				// スクリーンタッチ情報更新
				Ctrl.tx = tx - Ctrl.sbox.x;
				Ctrl.ty = ty - Ctrl.sbox.y;
				Ctrl.tdn = true;
				Ctrl.tmv = false;
				Ctrl._temptx = Ctrl.tx;
				Ctrl._tempty = Ctrl.ty;
			}else{
				// コントローラタッチ情報更新
				Ctrl._calcTouchButton(box, tx, ty, true, false);
			}
			return true;
		});

		// 上位ノードイベントキャンセル
		e.preventDefault();
		e.stopPropagation();
	}

	// ----------------------------------------------------------------
	// ルート要素 タッチ移動
	static function _tmvfn(e : Event) : void{
		Ctrl._calcEvent(e, function(tx : int, ty : int, id : int) : boolean{
			// マルチタッチ情報確認
			var box : Ctrl.Box = null;
			for(var i = 0; i < Ctrl._info.length; i++){if(id == Ctrl._info[i].id){box = Ctrl._info[i].box; break;}}
			if(box == null){return false;}

			if(box == Ctrl.sbox){
				// スクリーンタッチ情報更新
				Ctrl.tx = tx - Ctrl.sbox.x;
				Ctrl.ty = ty - Ctrl.sbox.y;
				if(Ctrl.tdn && !Ctrl.tmv){
					var x = Ctrl._temptx - Ctrl.tx;
					var y = Ctrl._tempty - Ctrl.ty;
					Ctrl.tmv = (x * x + y * y > 10);
				}
			}else{
				// コントローラタッチ情報更新
				Ctrl._calcTouchButton(box, tx, ty, false, false);
			}
			return true;
		});

		// 上位ノードイベントキャンセル
		e.preventDefault();
		e.stopPropagation();
	}

	// ----------------------------------------------------------------
	// ルート要素 タッチ完了
	static function _tupfn(e : Event) : void{
		Ctrl._calcEvent(e, function(tx : int, ty : int, id : int) : boolean{
			// マルチタッチ情報確認
			var box : Ctrl.Box = null;
			for(var i = 0; i < Ctrl._info.length; i++){if(id == Ctrl._info[i].id){box = Ctrl._info.splice(i--, 1)[0].box; break;}}
			if(box == null){return false;}

			if(box == Ctrl.sbox){
				// スクリーンタッチ情報更新
				Ctrl.tx = tx - Ctrl.sbox.x;
				Ctrl.ty = ty - Ctrl.sbox.y;
				Ctrl.tdn = false;
			}else{
				// コントローラタッチ情報更新
				Ctrl._calcTouchButton(box, tx, ty, false, true);
			}
			return true;
		});

		// 上位ノードイベントキャンセル
		e.preventDefault();
		e.stopPropagation();
	}

	// ----------------------------------------------------------------
	// 範囲設定クラス
	class Box{
		var x : int;
		var y : int;
		var w : int;
		var h : int;
		function constructor(x : int, y : int, w : int, h : int){
			this.x = x;
			this.y = y;
			this.w = w;
			this.h = h;
		}
	}

	// ----------------------------------------------------------------
	// マルチタッチ情報管理クラス
	class _TouchInfo{
		var id : int;
		var box : Ctrl.Box;
		function constructor(id : int, box : Ctrl.Box){
			this.id = id;
			this.box = box;
		}
	}
}

// ----------------------------------------------------------------
// ----------------------------------------------------------------
// ----------------------------------------------------------------
//


koh5_pano



Your browser does not support the HTML5 canvas element.


Drag mouse to navigate.

Navigation





17.Aug.2010, Martin Wengenmayer