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

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

?? graph.js

?? 使用javascript腳本實現IE的拖拽
?? 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一区二区三区免费野_久草精品视频
欧美视频日韩视频在线观看| 久久亚洲一区二区三区四区| 精品国精品国产尤物美女| 国产精品私人影院| 蜜臀av一区二区三区| av色综合久久天堂av综合| 日韩欧美一级二级| 亚洲激情第一区| 丁香婷婷综合激情五月色| 欧美一区二区视频网站| 亚洲精品国产a| 成人黄页毛片网站| 久久久亚洲国产美女国产盗摄| 亚洲成人久久影院| 99久久国产综合精品女不卡| 久久婷婷综合激情| 免费一级欧美片在线观看| 91福利在线播放| 中文字幕亚洲综合久久菠萝蜜| 国产一区久久久| 日韩欧美不卡在线观看视频| 天堂蜜桃91精品| 欧美性色黄大片| 亚洲免费资源在线播放| 99精品视频一区| 国产精品久久久久一区二区三区| 国内精品国产三级国产a久久| 91精品国产综合久久久久久漫画| 一区二区三区四区亚洲| 91视频国产观看| 日韩美女视频一区| av成人免费在线观看| 欧美激情在线观看视频免费| 国产老肥熟一区二区三区| 久久亚洲欧美国产精品乐播 | 欧美伊人久久大香线蕉综合69| 国产精品高潮呻吟| 成人毛片视频在线观看| 国产精品久久久久久久久晋中| 成人黄色a**站在线观看| 国产精品美日韩| 国产精华液一区二区三区| 久久久99精品免费观看不卡| 国产二区国产一区在线观看| 26uuu另类欧美| 国产成人免费视频| 18成人在线观看| 一本色道久久综合亚洲91 | 成人永久免费视频| 国产精品―色哟哟| 91蜜桃视频在线| 亚洲成在线观看| 91精品国产免费久久综合| 精品一区二区在线观看| 国产女主播在线一区二区| 91在线免费播放| 亚洲超碰精品一区二区| 欧美成人综合网站| 成人一区二区三区视频在线观看| 亚洲男人天堂av网| 91精品福利在线一区二区三区| 九色porny丨国产精品| 国产欧美日韩三级| 欧美午夜影院一区| 激情图片小说一区| 亚洲欧美色一区| 日韩欧美国产麻豆| 不卡高清视频专区| 三级久久三级久久| 中文在线免费一区三区高中清不卡| 91网站视频在线观看| 免费高清在线一区| 成人免费一区二区三区视频| 91麻豆精品国产91久久久久久 | 国产欧美视频一区二区| 欧美亚洲综合在线| 国产一区二区三区国产| 夜夜夜精品看看| 久久久久99精品国产片| 在线观看亚洲一区| 国产不卡视频在线播放| 亚洲国产精品综合小说图片区| 精品国产不卡一区二区三区| 91福利社在线观看| 国产二区国产一区在线观看 | 国产视频不卡一区| 欧美人与性动xxxx| 91亚洲精品乱码久久久久久蜜桃| 午夜日韩在线观看| 亚洲色图20p| 久久婷婷国产综合精品青草| 欧美色男人天堂| 丰满少妇久久久久久久| 免费久久99精品国产| 一区二区理论电影在线观看| 国产区在线观看成人精品 | 精品国产1区2区3区| 欧美日韩精品一区二区三区四区| 成人av片在线观看| 国产精品18久久久久久久久久久久 | 欧美一级二级在线观看| 欧美伊人久久大香线蕉综合69| 国产成人精品亚洲777人妖| 免费高清不卡av| 日韩av一区二区三区| 亚洲资源中文字幕| 一区二区三区精品| 亚洲色欲色欲www| 国产精品不卡一区| 国产精品热久久久久夜色精品三区| 精品噜噜噜噜久久久久久久久试看| 欧美久久婷婷综合色| 欧美日韩在线播放一区| 欧洲精品一区二区三区在线观看| 91在线无精精品入口| 99精品视频一区| 日本久久一区二区| 欧洲激情一区二区| 欧美视频在线不卡| 欧美精品久久久久久久久老牛影院| 欧美午夜一区二区三区免费大片| 在线视频一区二区三| 欧美日本在线视频| 欧美精品第一页| 日韩一级视频免费观看在线| 欧美成人免费网站| 久久女同互慰一区二区三区| 久久久久久久久久看片| 国产欧美综合在线观看第十页| 国产欧美一区二区三区在线看蜜臀 | 波多野结衣中文字幕一区 | 亚洲国产精品久久艾草纯爱| 亚洲成av人影院| 蜜芽一区二区三区| 精品一区二区三区香蕉蜜桃| 国产精品综合久久| a级高清视频欧美日韩| 在线一区二区三区四区五区| 欧美日韩高清不卡| 26uuu亚洲综合色| 国产精品日产欧美久久久久| 亚洲精品日韩综合观看成人91| 亚洲v日本v欧美v久久精品| 麻豆成人av在线| 不卡电影免费在线播放一区| 欧美午夜精品免费| 精品国精品自拍自在线| √…a在线天堂一区| 亚洲一区二区精品3399| 久久99精品久久久久久久久久久久 | 日本午夜精品一区二区三区电影| 国产在线播放一区三区四| 成人av在线看| 欧美久久久久久久久| 久久久久国产免费免费| 亚洲综合小说图片| 国产一区在线精品| 欧美在线免费播放| 2020国产精品| 午夜亚洲国产au精品一区二区| 激情图片小说一区| 欧日韩精品视频| 久久精品一区四区| 亚洲va国产天堂va久久en| 国产精品系列在线观看| 欧美人牲a欧美精品| 国产精品动漫网站| 青青草成人在线观看| 成人av电影在线观看| 欧美成人精品福利| 亚洲一卡二卡三卡四卡五卡| 国产精品1024| 日韩一区二区视频| 亚洲色图都市小说| 99re视频精品| 精品久久久久久综合日本欧美| 亚洲精品久久7777| 成a人片国产精品| 久久综合久久鬼色| 日韩av一级片| 欧美日韩精品一区二区天天拍小说 | 91麻豆swag| 久久人人爽人人爽| 免费观看一级特黄欧美大片| 99久久精品国产导航| 国产欧美精品一区| 激情综合色综合久久| 欧美久久一二区| 一级精品视频在线观看宜春院| 成人性色生活片免费看爆迷你毛片| 日韩一区二区三区电影在线观看| 亚洲欧美日韩一区二区三区在线观看| 国产精品亚洲一区二区三区妖精| 欧美成人精品高清在线播放| 午夜久久电影网| 欧美性视频一区二区三区| 亚洲人123区| 91黄色在线观看| 亚洲精品成a人| 99国产精品一区|