亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? graph.js

?? 使用javascript在網頁上畫圖
?? JS
字號:
/*
*  作者: scriptfans(琳琳的小狗)
*  QQ: 99352246


/*
 * 可觀察模塊,供mixin使用
 */
var ObserveAble = {
	fire: function(name,memo){
		if(Object.isArray(this.observes)){
			this.observes.invoke(name,memo);
		}
	},
	observe: function(observe){
		if(Object.isArray(this.observes) && !this.observes.include(observe))
			this.observes.push(observe);
	},
	stopObserving: function(observe){
		if(Object.isArray(this.observes))
			this.observes = this.observes.without(observe);
	}
}

/*
 * 模型
 */
var VertexModel = Class.create({
	initialize: function(id,x,y,type){
		this.id = id;
		this.offsetX = x||0;
		this.offsetY = y||0;
		this.type = type||"";
		this.observes = [];
	},
	setOffset: function(x,y){
		this.offsetX = x;
		this.offsetY = y;
		this.fire("onOffsetChange");
	}
},ObserveAble);

var EdgeModel = Class.create({
	initialize: function(start,end,type){
		this.type = type;
		this.start = start;
		this.end = end;
		this.observes = [];
	},
	modify: function(edge){
		Object.keys(edge).without("observes").each(function(property){
			if(edge.hasOwnProperty(property) && this[property]!=edge[property])
				this[property] = edge[property];
		}, this);
	},
	ownerVertex: function(vertex){
		return [this.start, this.end].include(vertex);
	}
},ObserveAble);

var GraphModel = Class.create({
	initialize: function(){
		this.vertexs = [];
		this.edges = [];
		this.observes = [];
	},
	addVertex: function(vertex){
		var existed = this.vertexs.any(function(v){
			return v.id==vertex.id;
		});
		if(!existed){
			this.vertexs.push(vertex);
			this.fire("onAddVertex",vertex);
		}
	},
	removeVertex: function(vertex){
		this.edges.each(function(edge){
			if(edge.ownerVertex(vertex)){
				this.removeEdge(edge);
			}
		},this);
		var index = this.vertexs.indexOf(vertex);
		this.vertexs.splice(index,1);
			
		this.fire("onRemoveVertex",vertex);
	},
	addEdge: function(edge){
		var existed = this.edges.find(function(item){
			var intersect = [item.start,item.end].intersect([edge.start,edge.end]);
			return intersect.size()==2;
		});
		if(existed){
			existed.modify(edge);
			this.fire("onModifyEdge",edge);
		}else{
			this.edges.push(edge)
			this.fire("onAddEdge",edge);
		}
	},
	removeEdge: function(edge){
		this.edges = this.edges.without(edge);
		this.fire("onRemoveEdge",edge);
	},
	findVertex: function(id){
		return this.vertexs.find(function(vertex){
			return vertex.id == id;
		});
	}
}, ObserveAble);


/*
 * 視圖
 */
var GraphView = Class.create({
	initialize: function(options){
		this.options = Object.extend({
			wrap: "canvas",
			draggable: true,
			deleteable: true,
			drawable: "unilateral",
			toolbar: "toolbar",
			side: 8
		},options);
		
		this.active = null;
	},
	//關聯控制器,初始化視圖顯示
	show: function(model,controller){
		this.model = model;
		this.controller = controller;
		this.element = $(this.options.wrap);
		
		if(this.options.toolbar){
			this.initDrop(this.options.toolbar);
		}
		var canvas = this.element.getElementsByTagName("canvas");
		this.main_ctx = canvas[0].getContext("2d");
		if(this.options.drawable){
			this.line_handles = [];
			this.sub_ctx = canvas[1].getContext("2d");
			this.initDraw();
		}
		
		if(this.options.deleteable){
			//添加刪除事件
			document.observe("keydown",this.remove.bindAsEventListener(this));
		}
		
	},
	//刪除當前選中的邊,或者頂點
	remove: function(event){
		if(event.keyCode==Event.KEY_DELETE){
			if(this.active){
				if(this.active.constructor==EdgeModel){
					var edge = this.active;
					this.active = null;
					this.controller.removeEdge(edge);
				}else if(this.active.constructor==VertexModel){
					var vertex = this.active;
					this.active = null;
					this.controller.removeVertex(vertex);
				}
			}
		}
	},
	initDrop: function(toolbar){
		Droppables.add(this.element,{
			containment: toolbar,
			//拖放結束回調函數,在此處執行自定義操作
			onDrop: function(element){
				//根據邊欄拖放圖標信息生成節點id
				if(!$(element.id+"_")){
					var top = element.cumulativeOffset().top 
								- this.element.cumulativeOffset().top;
					var left = element.cumulativeOffset().left 
								- this.element.cumulativeOffset().left;
					this.controller.addVertex(element.id+"_", left, top);
				}
			}.bind(this)
		});
	},
	initDrag: function(dom){
		var drag = new Draggable(dom,{
			snap: this.snap,
			revert: this.revert.bind(this),
			reverteffect: function(element, top_offset, left_offset){
		        var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
		        new Effect.Move(element, { x: -left_offset, y: -top_offset,
					duration: dur, afterUpdate: this.update.bind(this)
				});
	      }.bind(this),
		  onDrag: this.update.bind(this),
		  onEnd: this.update.bind(this)
		});
	},
	//控制拖動行為
	snap: function(x, y, draggable){
		function constrain(n, lower, upper) {
			if (n > upper) return upper;
				return (n < lower ? lower : n);
		};
		var elementDims = draggable.element.getDimensions();
		var parentDims = Element.getDimensions(draggable.element.parentNode);
		
		x = constrain(x, 0, parentDims.width - elementDims.width);
		y = constrain(y, 0, parentDims.height - elementDims.height);
		return [x,y];
	},
	revert: function(element){
		var width = element.getWidth();
		var height = element.getHeight();
		
		var dragCumOffset = element.cumulativeOffset();
		var left = dragCumOffset.left;
		var top = dragCumOffset.top;
		
		var left_top = [left,top];
		var right_top = [left + width,top];
		var left_bottom = [left, top + height];
		var right_bottom = [left + width, top + height];
		
		var corners = [left_top, right_top, left_bottom, right_bottom];

		for (var i = 0; i < this.model.vertexs.size(); i++) {
			var vertex = this.model.vertexs[i];
			if (vertex.id == element.id) continue;
			
			var other = $(vertex.id);
			var other_width = other.getWidth();
			var other_height = other.getHeight();
			
			var other_offset = other.cumulativeOffset();
			var other_left = other_offset.left;
			var other_top = other_offset.top;
			
			var other_left_top = [other_left,other_top];
			var other_right_top = [other_left + other_width,other_top];
			var other_left_bottom = [other_left, other_top + other_height];
			var other_right_bottom = [other_left + other_width, other_top + other_height];
			//是否重疊	
			var overlap = !( left_top[0] > other_right_bottom[0] ||
			              right_bottom[1] <other_left_top[1] ||
			              right_bottom[0] < other_left_top[0] ||
			              left_top[1] > other_right_bottom[1] );

			if(overlap) return true;
		}
		return false;
	},
	initDraw: function(){
		this.element.observe("graph:drawline",function(event){
			var dim = this.element.getDimensions();
			this.sub_ctx.clearRect(0,0,dim.width,dim.height);
			this.sub_ctx.strokeStyle = "rgba(0,0,255,0.5)";
			this.sub_ctx.beginPath();
			
			var startPosition = this.getCenter(event.memo.element);
			this.sub_ctx.moveTo(startPosition[0],startPosition[1]);
			var new_x = event.memo.endX-this.element.cumulativeOffset().left;
			var new_y = event.memo.endY-this.element.cumulativeOffset().top;
			this.sub_ctx.lineTo(new_x,new_y);
			this.sub_ctx.stroke();
		}.bind(this));
		
		var button = $(this.options.drawable);
		
		button.observe("click",this.draw.bind(this));
	},
	draw: function(event){
		//取消繪圖按鈕點擊事件
		var button = event.element();
		button.stopObserving("click");
		
		this.element.observe("click",function(event){
			this.element.stopObserving("click");
			var start = event.element();
			
			if(start.hasClassName("vertex") && !start.hasClassName("start")){
				//防止移動鼠標畫線未結束時刪除起始點
				document.stopObserving("keydown");
				
				start.addClassName("start");
				this.element.observe("mousemove",function(event){
					var endX = event.pointerX();
					var endY = event.pointerY();
					this.fire("graph:drawline",{element:start,endX:endX,endY:endY});
					var element = event.element();
					if(element.hasClassName("vertex")){
						if(!element.hasClassName("start")){
							element.addClassName("end");
						}else{
							return;
						}
					}else{
						$$("div.end").invoke("removeClassName","end");
					}
				});
				
				this.element.observe("click",function(event){
					this.element.stopObserving("mousemove");
					this.element.stopObserving("click");
					
					var end = event.element();
					if(end.hasClassName("vertex") && end.hasClassName("end")){
						this.controller.addEdge(start.vertex,end.vertex);
					}
					var dim = this.element.getDimensions();
					this.sub_ctx.clearRect(0,0,dim.width,dim.height);
					$$("div.start").invoke("removeClassName","start");
					$$("div.end").invoke("removeClassName","end");
					
					if(this.options.deleteable){
						//恢復鍵盤刪除事件
						document.observe("keydown",this.remove.bindAsEventListener(this));
					}
					//回復繪圖按鈕點擊事件
					button.observe("click",this.draw.bind(this));
					
				}.bind(this));
			}else{
				button.observe("click",this.draw.bind(this));
			}
		}.bind(this));
	},
	getCenter: function(dom){
		dom = $(dom);
		var pos = dom.positionedOffset();
		var width = dom.getWidth();
		var height = dom.getHeight();

		return [pos.left+width/2, pos.top+height/2];
	},
	select: function(obj){
		if(obj!=this.active){
			if(this.active && this.active.constructor==VertexModel){
				$(this.active.id).removeClassName("active");
			}
			
			var flag = obj.constructor==EdgeModel || (this.active && this.active.constructor==EdgeModel);
			this.active = obj;
			if(flag) this.update();
			
			if(this.active.constructor==VertexModel){
				$(this.active.id).addClassName("active");
			}
		}
	},
	//重繪主畫板線段
	update: function(){
		this.main_ctx.clearRect(0,0,400,400);
		
		this.model.edges.each(this.showLine.bind(this));
		this.line_handles.invoke("show");
	},
	showLine: function(edge){
		var color = (this.active == edge)?"#FF0000":"#0000FF";
		var start = this.getCenter($(edge.start.id));
		var end = this.getCenter($(edge.end.id));
				
		var context = this.main_ctx;
		context.beginPath();
		context.moveTo(start[0],start[1])
		context.lineTo(end[0],end[1]);
		context.strokeStyle = context.fillStyle = color;
		context.stroke();
		
		if(edge.type=="unilateral"){
			context.save();
			var mid_x = (end[0]-start[0])/2 + start[0];
			var mid_y = (end[1]-start[1])/2 + start[1];
			context.translate(mid_x,mid_y);
			var arc = (end[1]-start[1])/(end[0]-start[0]);
			arc = isNaN(arc)?0:arc;
			context.rotate(Math.atan(arc));
	
			var side = this.options.side;
			var r = side/2/Math.cos(Math.PI/6);
			var reverse = side/2*Math.tan(Math.PI/6);
			
			if(end[0]>=start[0]){
				context.moveTo(r,0);
				context.lineTo(-reverse,side/2);
				context.moveTo(r,0);
				context.lineTo(-reverse,-side/2);
			}else{
				context.moveTo(-r,0);
				context.lineTo(reverse,side/2);
				context.moveTo(-r,0);
				context.lineTo(reverse,-side/2);
			}
			context.stroke();
			context.restore();
		}
	},
	//新增節點回調函數
	onAddVertex: function(vertex){
		var hash = {igate:"igate節點",dit:"dit節點",dat:"dat節點"}
		var dom = new Element("div", {id:vertex.id, "class":"vertex"})
		.setStyle({
			top: vertex.offsetY + "px",
			left: vertex.offsetX + "px"
		}).addClassName(vertex.type).update(hash[vertex.type]);
		
		if(vertex.type=="dit"){
			dom.setStyle({width:"30px",height:"30px"});
		}
		
		dom.vertex = vertex;
		this.element.insert(dom);
		
		dom.observe("mousedown", this.select.bind(this,vertex));
		
		if(this.options.draggable){
			this.initDrag(dom);
		}
		
		this.select(vertex);
	},
	onRemoveVertex: function(vertex){
		Element.remove(vertex.id);
	},
	//新增連線回調函數
	onAddEdge: function(edge){
		this.line_handles.push(new LineHandle(edge, this, this.element));
		this.update();
	},
	//修改連線回調函數
	onModifyEdge: function(edge){
		this.update();
	},
	onRemoveEdge: function(edge){
		var line_handle = this.line_handles.find(function(h){
			return h.edge == edge;
		});
		if(line_handle){
			this.line_handles = this.line_handles.without(line_handle);
			line_handle.handle.remove();
		}
		this.update();
	}
});

var LineHandle = Class.create({
	initialize: function(model, view, parent){
		this.edge = model;
		this.view = view;
		this.handle = new Element("div",{"class":"arrow"}).hide();
		parent.insert(this.handle);
		this.handle.observe("mousedown",this.select.bind(this));
	},
	select: function(event){
		this.view.select(this.edge);
	},
	show: function(){
		var start = this.view.getCenter($(this.edge.start.id));
		var end = this.view.getCenter($(this.edge.end.id));
		var x = (end[0]-start[0])/2 + start[0];
		var y = (end[1]-start[1])/2 + start[1];
		var r = this.view.options.side/2/Math.cos(Math.PI/6);
		
		var left = x-r;
		var top = y-r;
		this.handle.setStyle({
			left: left + "px",
			top: top + "px",
			width: 2*r + "px",
			height: 2*r + "px"
		}).show();
	}
})


/*
 * 控制器
 */
var GraphController = Class.create({
	initialize: function(model,view){
		this.model = model;
		this.view = view;
		//注冊視圖為模型的監聽器
		this.model.observe(this.view);
		//顯示視圖
		this.view.show(model,this);
	},
	addVertex: function(id,x,y,type){
		this.model.addVertex(new VertexModel(id,x,y,type));
		return this;
	},
	removeVertex: function(vertex){
		this.model.removeVertex(vertex);
		return this;
	},
	setVertexOffset: function(x,y){
		
	},
	addEdge: function(start, end, type){
		type = type || "unilateral";
		this.model.addEdge(new EdgeModel(start, end, type));
	},
	removeEdge: function(edge){
		this.model.removeEdge(edge);
	}
});





?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
91丨porny丨户外露出| 亚洲精品视频免费看| 蜜臀久久99精品久久久久宅男 | 成年人国产精品| 精品一区二区三区欧美| 欧美一区二区三区啪啪| 欧美日韩国产乱码电影| 色系网站成人免费| 91一区二区在线观看| 国产一区欧美日韩| 日本欧美一区二区| 免费xxxx性欧美18vr| 亚洲欧美在线另类| 亚洲自拍偷拍av| 国产午夜亚洲精品不卡 | 久久综合色播五月| 精品一区二区在线看| 欧美电影免费观看高清完整版在线观看 | 99在线热播精品免费| 久久久欧美精品sm网站| 成人av资源下载| 亚洲欧洲日韩在线| 色哟哟精品一区| 亚洲三级在线播放| 日韩午夜在线影院| 国产一区二区在线观看免费| 国产视频一区在线观看| 国产在线视频精品一区| 国产免费久久精品| 色哟哟精品一区| 香港成人在线视频| 久久久久88色偷偷免费| 91小视频免费看| 日韩电影在线一区| 国产日韩综合av| 欧美一区二区日韩| 激情五月播播久久久精品| 亚洲国产精品ⅴa在线观看| 国产乱子伦视频一区二区三区| 亚洲伦在线观看| 日韩欧美成人一区| 91小宝寻花一区二区三区| 一区二区三区中文在线观看| 欧美变态tickling挠脚心| 成人免费高清在线| 亚洲靠逼com| 成人在线一区二区三区| 91精品国产欧美一区二区18 | 成人在线一区二区三区| 欧美在线观看一区| 日韩免费高清av| 亚洲精品中文字幕乱码三区| 秋霞电影一区二区| 亚洲妇女屁股眼交7| 成人高清视频免费观看| 亚洲国产人成综合网站| 久久精品夜色噜噜亚洲aⅴ| 高潮精品一区videoshd| 爽好久久久欧美精品| 亚洲视频电影在线| 国产亚洲欧美一级| 欧美日韩精品欧美日韩精品一 | 国产亚洲精品久| 欧美日韩一卡二卡| 国产jizzjizz一区二区| 视频一区二区不卡| 1区2区3区欧美| 久久综合色天天久久综合图片| 欧美日韩中字一区| 国产成人av电影在线观看| 蜜桃av噜噜一区| 一区二区高清视频在线观看| 国产欧美一二三区| 欧美变态tickling挠脚心| 日韩一级二级三级| 精品久久五月天| 久久久无码精品亚洲日韩按摩| 欧美精品一区在线观看| 亚洲精品一区二区三区精华液| 精品福利在线导航| 久久婷婷一区二区三区| 国产日本亚洲高清| 欧美激情综合在线| 亚洲三级电影全部在线观看高清| 亚洲人快播电影网| 樱桃视频在线观看一区| 亚洲国产精品欧美一二99| 亚洲不卡一区二区三区| 日韩黄色在线观看| 国内成人精品2018免费看| 国产成人午夜精品影院观看视频| 懂色av一区二区夜夜嗨| 972aa.com艺术欧美| 日本精品一区二区三区四区的功能| 91免费观看视频| 欧美日韩二区三区| 精品国产欧美一区二区| 欧美韩日一区二区三区四区| 亚洲男人的天堂网| 午夜精品免费在线| 国产一区二区三区免费播放 | 免费在线观看视频一区| 国产成人啪免费观看软件| 91视频在线看| 欧美一区二区三区在线视频| 欧美精品一区男女天堂| 亚洲日本va在线观看| 青草av.久久免费一区| 大尺度一区二区| 色999日韩国产欧美一区二区| 欧美一区二区不卡视频| 久久精品亚洲一区二区三区浴池| 亚洲六月丁香色婷婷综合久久 | 2欧美一区二区三区在线观看视频| 欧美国产欧美综合| 亚洲一区二区三区中文字幕| 另类综合日韩欧美亚洲| 色综合久久久久综合99| 日韩三级中文字幕| 综合中文字幕亚洲| 国产一区福利在线| 欧美日韩亚洲另类| 国产亚洲视频系列| 亚洲成va人在线观看| 成人福利电影精品一区二区在线观看| 在线观看视频欧美| 久久嫩草精品久久久精品| 亚洲狠狠爱一区二区三区| 国产成人午夜视频| 日韩视频免费观看高清在线视频| 国产精品久久影院| 国产一区二区三区美女| 欧美日本在线观看| 亚洲欧美激情一区二区| 国产.欧美.日韩| 精品久久久久av影院| 丝袜美腿亚洲色图| 在线精品视频一区二区三四| 国产女同互慰高潮91漫画| 久久国产精品露脸对白| 欧美日韩成人综合天天影院| 亚洲色图.com| 99在线精品一区二区三区| 国产婷婷色一区二区三区| 蜜桃视频免费观看一区| 欧美日韩一本到| 亚洲精品乱码久久久久久久久 | 亚洲人成7777| 国产成人啪免费观看软件| ww久久中文字幕| 开心九九激情九九欧美日韩精美视频电影| 91福利在线导航| 一区二区在线看| 色天天综合久久久久综合片| 国产精品第四页| eeuss鲁一区二区三区| 中文字幕国产一区二区| 成人性视频免费网站| 久久久精品影视| 国产精品影视天天线| 国产亚洲精品资源在线26u| 国产一区二区三区综合| 337p日本欧洲亚洲大胆精品| 国内一区二区在线| 精品国产亚洲在线| 国产剧情一区在线| www久久久久| 国产成a人亚洲精品| 国产日韩v精品一区二区| 国产乱子轮精品视频| 精品国产乱码久久| 国产精品一区二区三区四区| 久久美女艺术照精彩视频福利播放| 久草精品在线观看| 久久久精品蜜桃| 国产精品一二三在| 国产精品毛片无遮挡高清| www.成人网.com| 一区二区三区不卡视频在线观看 | 制服.丝袜.亚洲.另类.中文| 日韩av中文字幕一区二区三区| 91麻豆精品国产综合久久久久久 | 一区二区三区国产| 91精品国产综合久久久久| 九九九久久久精品| 国产精品久久一级| 欧美视频一区二区三区在线观看| 日韩精品亚洲专区| 久久久精品综合| 在线精品国精品国产尤物884a| 日韩**一区毛片| 久久久久久免费| 日本韩国一区二区| 美女脱光内衣内裤视频久久网站| 欧美精品一区视频| 日本精品免费观看高清观看| 美女视频网站黄色亚洲| 在线成人av网站| 亚洲综合在线免费观看| 青青青伊人色综合久久|