在好例子网,分享、交流、成长!
您当前所在位置:首页js 开发实例JavaScript基础 → js-node-graph 示例源码

js-node-graph 示例源码

JavaScript基础

下载此实例
  • 开发语言:js
  • 实例大小:3.76KB
  • 下载次数:3
  • 浏览次数:21
  • 发布时间:2018-05-17
  • 实例类别:JavaScript基础
  • 发 布 人:madeindeer
  • 所需积分:2
 相关标签: node

实例介绍

【实例简介】

【实例截图】

from clipboard

【核心代码】

// base canvas
var svg = document.getElementById("svg");
svg.ns = svg.namespaceURI;

var mouse = {
	currentInput: null,
	createPath: function(a, b) {
		var diff = {
			x: b.x - a.x,
			y: b.y - a.y
		};

		var pathStr = "M"   a.x   ","   a.y   " ";
		pathStr  = "C";
		pathStr  = a.x   diff.x / 3 * 2   ","   a.y   " ";
		pathStr  = a.x   diff.x / 3   ","   b.y   " ";
		pathStr  = b.x   ","   b.y;

		return pathStr;
	}
};

window.onmousemove = function(e) {
	if (mouse.currentInput) {
		var p = mouse.currentInput.path;
		var iP = mouse.currentInput.getAttachPoint();
		var oP = { x: e.pageX, y: e.pageY };
		var s = mouse.createPath(iP, oP);
		p.setAttributeNS(null, "d", s);
	}
};

window.onclick = function(e) {
	if (mouse.currentInput) {
		mouse.currentInput.path.removeAttribute("d");
		if (mouse.currentInput.node) {
			mouse.currentInput.node.detachInput(mouse.currentInput);
		}
		mouse.currentInput = null;
	}
};

function GetFullOffset(element) {
	var offset = {
		top: element.offsetTop,
		left: element.offsetLeft
	};

	if (element.offsetParent) {
		var po = GetFullOffset(element.offsetParent);
		offset.top  = po.top;
		offset.left  = po.left;
		return offset;
	} else return offset;
}

function Node(name) {
	// DOM Element creation
	this.domElement = document.createElement("div");
	this.domElement.classList.add("node");
	this.domElement.setAttribute("title", name);

	// Create output visual
	var outDom = document.createElement("span");
	outDom.classList.add("output");
	outDom.innerHTML = " ";
	this.domElement.appendChild(outDom);

	// Output Click handler
	var that = this;
	outDom.onclick = function(e) {
		if (mouse.currentInput && !that.ownsInput(mouse.currentInput)) {
			var tmp = mouse.currentInput;
			mouse.currentInput = null;
			that.connectTo(tmp);
		}
		e.stopPropagation();
	};

	// Node Stuffs
	this.value = "";
	this.inputs = [];
	this.connected = false;

	// SVG Connectors
	this.attachedPaths = [];
}

function NodeInput(name) {
	this.name = name;
	this.node = null;

	// setup the varying input types
	this.domElement = document.createElement("div");
	this.domElement.innerHTML = name;
	this.domElement.classList.add("connection");
	this.domElement.classList.add("empty");

	// svg link
	this.path = document.createElementNS(svg.ns, "path");
	this.path.setAttributeNS(null, "stroke", "#8e8e8e");
	this.path.setAttributeNS(null, "stroke-width", "2");
	this.path.setAttributeNS(null, "fill", "none");
	svg.appendChild(this.path);

	// DOM Event handlers
	var that = this;
	this.domElement.onclick = function(e) {
		if (mouse.currentInput) {
			if (mouse.currentInput.path.hasAttribute("d"))
				mouse.currentInput.path.removeAttribute("d");
			if (mouse.currentInput.node) {
				mouse.currentInput.node.detachInput(mouse.currentInput);
				mouse.currentInput.node = null;
			}
		}
		mouse.currentInput = that;
		if (that.node) {
			that.node.detachInput(that);
			that.domElement.classList.remove("filled");
			that.domElement.classList.add("empty");
		}
		e.stopPropagation();
	};
}

NodeInput.prototype.getAttachPoint = function() {
	var offset = GetFullOffset(this.domElement);
	return {
		x: offset.left   this.domElement.offsetWidth - 2,
		y: offset.top   this.domElement.offsetHeight / 2
	};
};

Node.prototype.getOutputPoint = function() {
	var tmp = this.domElement.firstElementChild;
	var offset = GetFullOffset(tmp);
	return {
		x: offset.left   tmp.offsetWidth / 2,
		y: offset.top   tmp.offsetHeight / 2
	};
};

Node.prototype.addInput = function(name) {
	var input = new NodeInput(name);
	this.inputs.push(input);
	this.domElement.appendChild(input.domElement);

	return input;
};

Node.prototype.detachInput = function(input) {
	var index = -1;
	for (var i = 0; i < this.attachedPaths.length; i  ) {
		if (this.attachedPaths[i].input == input) index = i;
	}

	if (index >= 0) {
		this.attachedPaths[index].path.removeAttribute("d");
		this.attachedPaths[index].input.node = null;
		this.attachedPaths.splice(index, 1);
	}

	if (this.attachedPaths.length <= 0) {
		this.domElement.classList.remove("connected");
	}
};

Node.prototype.ownsInput = function(input) {
	for (var i = 0; i < this.inputs.length; i  ) {
		if (this.inputs[i] == input) return true;
	}
	return false;
};

Node.prototype.updatePosition = function() {
	var outPoint = this.getOutputPoint();

	var aPaths = this.attachedPaths;
	for (var i = 0; i < aPaths.length; i  ) {
		var iPoint = aPaths[i].input.getAttachPoint();
		var pathStr = this.createPath(iPoint, outPoint);
		aPaths[i].path.setAttributeNS(null, "d", pathStr);
	}

	for (var j = 0; j < this.inputs.length; j  ) {
		if (this.inputs[j].node != null) {
			var iP = this.inputs[j].getAttachPoint();
			var oP = this.inputs[j].node.getOutputPoint();

			var pStr = this.createPath(iP, oP);
			this.inputs[j].path.setAttributeNS(null, "d", pStr);
		}
	}
};

Node.prototype.createPath = function(a, b) {
	var diff = {
		x: b.x - a.x,
		y: b.y - a.y
	};

	var pathStr = "M"   a.x   ","   a.y   " ";
	pathStr  = "C";
	pathStr  = a.x   diff.x / 3 * 2   ","   a.y   " ";
	pathStr  = a.x   diff.x / 3   ","   b.y   " ";
	pathStr  = b.x   ","   b.y;

	return pathStr;
};

Node.prototype.connectTo = function(input) {
	input.node = this;
	this.connected = true;
	this.domElement.classList.add("connected");

	input.domElement.classList.remove("empty");
	input.domElement.classList.add("filled");

	this.attachedPaths.push({
		input: input,
		path: input.path
	});

	var iPoint = input.getAttachPoint();
	var oPoint = this.getOutputPoint();

	var pathStr = this.createPath(iPoint, oPoint);

	input.path.setAttributeNS(null, "d", pathStr);
};

Node.prototype.moveTo = function(point) {
	this.domElement.style.top = point.y   "px";
	this.domElement.style.left = point.x   "px";
	this.updatePosition();
};

Node.prototype.initUI = function() {
	var that = this;

	// Make draggable
	$(this.domElement).draggable({
		containment: "window",
		cancel: ".connection,.output",
		drag: function(event, ui) {
			that.updatePosition();
		}
	});
	// Fix positioning
	this.domElement.style.position = "absolute";

	document.body.appendChild(this.domElement);

	// update.
	this.updatePosition();
};

// Test nodes.
var node01 = new Node("Generate Cube");
node01.addInput("Name");
node01.addInput("Size");

var node02 = new Node("Add");
node02.addInput("Left&nbsp;&nbsp;&nbsp;&nbsp;");
node02.addInput("Right&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");

var node03 = new Node("Translate");
node03.addInput("Object");
node03.addInput("X");
node03.addInput("Y");
node03.addInput("Z");

// Move and connect.
node01.moveTo({ x: 75, y: 125 });
node02.moveTo({ x: 350, y: 20 });
node03.moveTo({ x: 500, y: 150 });
node01.connectTo(node02.inputs[0]);
node03.connectTo(node02.inputs[1]);

// Add to canvas
node01.initUI();
node02.initUI();
node03.initUI();

标签: node

实例下载地址

js-node-graph 示例源码

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
;
报警
var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_4847253'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s13.cnzz.com/stat.php%3Fid%3D4847253' type='text/javascript'%3E%3C/script%3E"));