Skip to content
Snippets Groups Projects
index.html 6.04 KiB
Newer Older
  • Learn to ignore specific revisions
  • wonko's avatar
    wonko committed
    <!DOCTYPE html>
    <meta charset="utf-8">
    
    <head>
    	<title>Page Title</title>
    	<style>
    		circle {
    			fill: steelblue;
    			stroke: #fff;
    
    wonko's avatar
    wonko committed
    			stroke-width: 1px;
    
    wonko's avatar
    wonko committed
    		}
    
    		path {
    			fill: none;
    			stroke: #000;
    
    wonko's avatar
    wonko committed
    			stroke-width: 0px;
    
    wonko's avatar
    wonko committed
    		}
    	</style>
    
    
    </head>
    
    
    <body>
    	<script src="https://d3js.org/d3.v5.min.js"></script>
    
    
    wonko's avatar
    wonko committed
    	<div id='arrows'></div>
    
    wonko's avatar
    wonko committed
    
    	<script>
    
    
    wonko's avatar
    wonko committed
    
    		var arr_div = document.getElementById("arrows");
    		var width = arr_div.clientWidth;
    		var height = arr_div.clientHeight;
    
    
    
    		function arrows(svg_selector = "", path_id = "", segments = 8, thickness = 5) {
    			console.log(svg_selector);
    			if (svg_selector === "") {
    				var svg = d3.select("svg");
    			} else {
    				var svg = d3.select(svg_selector);
    			}
    			if (path_id === "") {
    
    				var path = svg.select("path").node();
    			} else {
    				var path = svg.select("#"+path_id).node();
    			}
    			console.log("svg "+svg);
    			console.log(path);
    
    			var l = path.getTotalLength();
    			var segs = 8;
    			var seg_l = l / segs;
    			var thickness = 5;
    			console.log(l, seg_l)
    			for (var i = 0; i < segs; i++) {
    				var start = i * seg_l;
    				var end = (i + 1) * seg_l;
    				console.log(i, start, start);
    				ar = new ArowOnPath(path, start, end);
    				svg.append("path")
    					.attr("d", ar.toString())
    					.attr("style", "fill:" + getRandomColorRgb());
    			}
    
    		}
    
    
    		d3.svg('path.svg').then(function (svg) {
    			svgnode = document.importNode(svg.documentElement, true);
    			console.log(svgnode);
    			d3.select("div#arrows").node().append(svgnode);
    			arrows("","path905");
    		});
    
    
    /*		var svg = d3.select("svgobject")
    			.attr("width", 100)
    
    wonko's avatar
    wonko committed
    			.attr("height", 500)
    			.attr("viewBox", "0 0 500 250");
    
    		var path = svg.append("path")
    
    wonko's avatar
    wonko committed
    			.attr("d", "m 148.72841,44.122751 c 24.39295,-6.887543 34.01192,11.961379 34.04221,25.595869 0.0303,13.63449 -22.99535,32.36853 -35.4467,32.64203 C 134.87257,102.63414 115.7832,72.134311 106.84906,60.736038 97.914925,49.337765 72.784255,30.266031 70.522257,21.15664 c -2.261998,-9.109391 -7.159135,-21.69117332 2.72304,-27.0895314 9.882175,-5.3983576 32.767453,-2.1532373 38.602383,-1.1928849 5.83492,0.9603523 14.42644,30.7694983 6.13055,38.7549313 -8.29588,7.985433 -41.770833,12.528576 -48.201026,12.493596 -6.430193,-0.03498 -22.799636,11.961369 -22.829921,25.595869 -0.03028,13.6345 23.982951,32.30489 39.33273,32.64203 15.349777,0.33714 38.055457,-51.350355 62.448397,-58.237899 z"
    
    wonko's avatar
    wonko committed
    			);
    
    wonko's avatar
    wonko committed
    */
    
    wonko's avatar
    wonko committed
    		function getRandomColorRgb() {
    			let red = Math.floor(Math.random() * 256);
    			let green = Math.floor(Math.random() * 256);
    			let blue = Math.floor(Math.random() * 256);
    			return `rgb(${red}, ${green}, ${blue})`;
    		}
    
    		function pointDist(point, distance, rad) {
    			return { x: point.x + distance * Math.cos(rad), y: point.y + distance * Math.sin(rad) };
    		}
    
    
    wonko's avatar
    wonko committed
    
    		// from https://github.com/d3/d3-shape/blob/master/src/curve/natural.js
    		function controlPoints(x) {
    			var i,
    				n = x.length - 1,
    				m,
    				a = new Array(n),
    				b = new Array(n),
    				r = new Array(n);
    			a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
    			for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
    			a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
    			for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
    			a[n - 1] = r[n - 1] / b[n - 1];
    			for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
    			b[n - 1] = (x[n] + a[n - 1]) / 2;
    			for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
    			return [a, b];
    		}
    
    
    
    
    wonko's avatar
    wonko committed
    		class ArowOnPath {
    
    wonko's avatar
    wonko committed
    			constructor(path, start, end, parts = 3, thickness = 5, angle = 2, padding = 1) {
    
    wonko's avatar
    wonko committed
    				this.path = path;
    
    				this.angle = angle;
    				this.thickness = thickness;
    
    wonko's avatar
    wonko committed
    				var length = end - start;
    
    wonko's avatar
    wonko committed
    				var partlen = (length - (2 * padding)) / (2 * parts);
    
    wonko's avatar
    wonko committed
    				console.log("ArrowOnPath", start, end, partlen);
    
    wonko's avatar
    wonko committed
    				this.p = [this.pointsAt(start + padding, (-1 * padding))];
    				for (var i = 1; i < (2 * parts); i++) {
    
    wonko's avatar
    wonko committed
    					this.p.push(this.pointsAt(start + (i * partlen)));
    				}
    
    wonko's avatar
    wonko committed
    				this.p.push(this.pointsAt(start + length - padding, (1 * padding)));
    
    wonko's avatar
    wonko committed
    			}
    			pointAngle(length) {
    				var p1 = this.path.getPointAtLength(length);
    				var p2 = this.path.getPointAtLength(length + 0.01);
    
    wonko's avatar
    wonko committed
    				if (p1.x == p2.x && p1.y == p2.y) {
    					p1 = this.path.getPointAtLength(length - 0.01);
    				}
    				console.log(p1, p2);
    
    wonko's avatar
    wonko committed
    				return Math.atan2((p2.y - p1.y), (p2.x - p1.x));
    
    			}
    			pointsAt(length, angleoffset = 0) {
    				var m = this.path.getPointAtLength(length);
    				var m_angle = this.pointAngle(length + angleoffset)
    
    wonko's avatar
    wonko committed
    				console.log("a", m_angle);
    
    wonko's avatar
    wonko committed
    				var a = {
    					x: m.x + (this.thickness * Math.cos(m_angle + this.angle))
    					, y: m.y + (this.thickness * Math.sin(m_angle + this.angle))
    				};
    
    				var b = {
    					x: m.x + (this.thickness * Math.cos(m_angle - this.angle))
    					, y: m.y + (this.thickness * Math.sin(m_angle - this.angle))
    				};
    
    				return { a: a, m: m, b: b }
    			}
    
    			p2s(point) {
    				return point.x.toString() + "," + point.y.toString();
    			}
    
    
    wonko's avatar
    wonko committed
    
    
    wonko's avatar
    wonko committed
    			d3path() {
    				var path = d3.path();
    				var i = 0
    
    wonko's avatar
    wonko committed
    
    
    wonko's avatar
    wonko committed
    				path.moveTo(this.p[i].m.x, this.p[i].m.y);
    				path.lineTo(this.p[i].a.x, this.p[i].a.y);
    
    
    wonko's avatar
    wonko committed
    				var nat = d3.curveNatural(path);
    				nat.lineStart();
    				for (var i = 0; i < this.p.length; i++) {
    					nat.point(this.p[i].a.x, this.p[i].a.y);
    
    				}
    				var px = controlPoints(nat._x),
    					py = controlPoints(nat._y);
    				var n = this.p.length;
    				var x = nat._x,
    					y = nat._y;
    				for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
    					path.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
    				}
    
    wonko's avatar
    wonko committed
    				i = this.p.length - 1;
    
    wonko's avatar
    wonko committed
    				path.lineTo(this.p[i].m.x, this.p[i].m.y);
    				path.lineTo(this.p[i].b.x, this.p[i].b.y);
    
    wonko's avatar
    wonko committed
    
    				nat.lineStart();
    
    wonko's avatar
    wonko committed
    				for (var i = this.p.length - 1; i >= 0; --i) {
    
    wonko's avatar
    wonko committed
    					nat.point(this.p[i].b.x, this.p[i].b.y);
    
    				}
    				var px = controlPoints(nat._x),
    					py = controlPoints(nat._y);
    				var n = this.p.length;
    				var x = nat._x,
    					y = nat._y;
    				for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
    					path.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
    				}
    
    
    wonko's avatar
    wonko committed
    				path.closePath();
    				return path;
    			}
    			toString() {
    				return this.d3path().toString();
    			}
    		}
    
    
    
    wonko's avatar
    wonko committed
    		/*var s = path.node()
    
    wonko's avatar
    wonko committed
    
    
    wonko's avatar
    wonko committed
    
    
    wonko's avatar
    wonko committed
    		*/
    
    wonko's avatar
    wonko committed
    
    	</script>
    
    </body>