String art in D3.
Last active
August 29, 2015 14:08
-
-
Save NPashaP/56731e158e74344e660e to your computer and use it in GitHub Desktop.
Nails And Strings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
circle{ | |
fill:#e0e0e0; | |
} | |
</style> | |
<body> | |
<section style="display:block;"> | |
Design: <select onchange="changeArt(this)"></select> | |
</section> | |
<svg width="960" height="480"> | |
<rect x="0" y="0" width="960" height="480"></rect> | |
<g id="strings"></g> | |
<g id="nails"></g> | |
</svg> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script src="sArt.js"> </script> | |
<script src="string designs.js"> </script> | |
<script> | |
function changeArt(t){ | |
d3.select("#nails").html(''); | |
d3.select("#strings").html(''); | |
sArt(sA[t.options[t.selectedIndex].value]); | |
} | |
d3.select("select").selectAll("option") | |
.data(sA.map(function(d){ return d.name;})) | |
.enter().append("option").attr("value",function(d,i){ return i;}) | |
.text(function(d){return d;}); | |
sArt(sA[0]); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function sArt(s){ | |
/* s should have the structure | |
{ name:, | |
nails:[{s:{x:,y:},e:{x:,y:},n:},...], | |
strings:[{n1:,n2:,se:,c:,th:},...], | |
nFlag: | |
} | |
where | |
name = name to identify the design, | |
nails = array of nail groups, | |
nails[i].s = coordinates of starting nail of i-th nail group, | |
nails[i].e = coordinates of ending nail of i-th nail group, | |
nails[i].n = number of nails in i-th nail group, | |
strings = array of strings, | |
strings[i].se = 0 if start nail is mapped to start nail of the groups, | |
strings[i].n1 = index of the first nail group in nails array for i-th string group, | |
strings[i].n2 = index of the second nail group in nails array for i-th string group, | |
strings[i].c = colour of strings for i-th string group, | |
strings[i].th = thickness for strings in i-th group, | |
nFlag = 0/1 flag to enable or disable the display of nails. | |
*/ | |
function drawNails(sa){ | |
sa.nails.forEach(function(d){ | |
var nr = 2;// nail radius | |
var p = d3.range(0,d.n+1).map(function(i){ | |
return {x:d.s.x+(i/d.n)*(d.e.x-d.s.x),y:d.s.y+(i/d.n)*(d.e.y-d.s.y)}; | |
}); | |
d3.select("#nails").append("g").selectAll("circle").data(p).enter().append("circle") | |
.attr("cx", function(d){ return d.x;}).attr("cy",function(d){ return d.y;}) | |
.attr("r",nr); | |
}); | |
} | |
function drawStrings(sa){ | |
sa.strings.forEach(function(d){ | |
var s1=sa.nails[d.n1].s; | |
var e1=sa.nails[d.n1].e; | |
var s2= d.se==0? sa.nails[d.n2].s : sa.nails[d.n2].e; | |
var e2= d.se==0? sa.nails[d.n2].e : sa.nails[d.n2].s; | |
//assume sa.nails[d.n1].n == sa.nails[d.n2].n; | |
var p = d3.range(0,sa.nails[d.n1].n+1).map(function(l){ | |
return {x1: s1.x + (l/sa.nails[d.n1].n)*(e1.x-s1.x), | |
y1: s1.y + (l/sa.nails[d.n1].n)*(e1.y-s1.y), | |
x2: s2.x + (l/sa.nails[d.n1].n)*(e2.x-s2.x), | |
y2: s2.y + (l/sa.nails[d.n1].n)*(e2.y-s2.y),}; | |
}); | |
d3.select("#strings").append("g").selectAll("line").data(p).enter().append("line") | |
.attr("x1",function(t){return t.x1;}).attr("y1",function(t){return t.y1;}) | |
.attr("x2",function(t){return t.x2;}).attr("y2",function(t){return t.y2;}) | |
.style("stroke", function(){ return d.c}).style("stroke-width", function(){ return d.th;}); | |
}); | |
} | |
if(s.nFlag==undefined || s.nFlag==1) drawNails(s); | |
drawStrings(s); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var sA = [ | |
(function(){ | |
var a = d3.range(0,6).map(function(a){ return a*2*Math.PI/6;}); | |
var r = 240, cx=480, cy=240, n=40; | |
var ret ={name:'Face',nails:[], strings:[],nFlag:0}; | |
ret.nails=a.map(function(a){ return {s:{x:cx, y:cy}, e:{x:cx+r*Math.cos(a), y:cy-r*Math.sin(a)},n:n};}); | |
ret.nails.push({s:ret.nails[0].e, e:ret.nails[1].e, n:n}); | |
ret.nails.push({s:ret.nails[2].e, e:ret.nails[3].e, n:n}); | |
ret.nails.push({s:ret.nails[4].e, e:ret.nails[5].e, n:n}); | |
ret.strings=[ | |
{n1:0, n2:6, se:0, c:"#ff0000", th:1}, | |
{n1:6, n2:1, se:1, c:"#ffaa00", th:1}, | |
{n1:1, n2:2, se:1, c:"#b2ff00", th:1}, | |
{n1:2, n2:7, se:0, c:"#00ff00", th:1}, | |
{n1:7, n2:3, se:1, c:"#00ffed", th:1}, | |
{n1:3, n2:4, se:1, c:"#0050ff", th:1}, | |
{n1:4, n2:8, se:0, c:"#7b00ff", th:1}, | |
{n1:8, n2:5, se:1, c:"#ff00aa", th:1}, | |
{n1:5, n2:0, se:1, c:"#ff004c", th:1} | |
]; | |
return ret; | |
})(),{ | |
name:'Stars', | |
nails:[ | |
{s:{x:10, y:240},e:{x:140, y:240},n:30}, | |
{s:{x:270, y:240},e:{x:400, y:240},n:30}, | |
{s:{x:530, y:240},e:{x:660, y:240},n:30}, | |
{s:{x:790, y:240},e:{x:920, y:240},n:30}, | |
{s:{x:205, y:45},e:{x:205, y:175},n:30}, | |
{s:{x:205, y:305},e:{x:205, y:435},n:30}, | |
{s:{x:465, y:45},e:{x:465, y:175},n:30}, | |
{s:{x:465, y:305},e:{x:465, y:435},n:30}, | |
{s:{x:725, y:45},e:{x:725, y:175},n:30}, | |
{s:{x:725, y:305},e:{x:725, y:435},n:30} | |
], | |
strings:[ | |
{n1:0, n2:4, se:1, c:"#DDD379", th:1}, | |
{n1:0, n2:5, se:0, c:"#DDD379", th:1}, | |
{n1:0, n2:6, se:1, c:"#DDD379", th:1}, | |
{n1:0, n2:7, se:0, c:"#DDD379", th:1}, | |
{n1:1, n2:4, se:0, c:"#DDD379", th:1}, | |
{n1:1, n2:5, se:1, c:"#DDD379", th:1}, | |
{n1:1, n2:6, se:1, c:"#DDD379", th:1}, | |
{n1:1, n2:7, se:0, c:"#DDD379", th:1}, | |
{n1:1, n2:8, se:1, c:"#DDD379", th:1}, | |
{n1:1, n2:9, se:0, c:"#DDD379", th:1}, | |
{n1:2, n2:4, se:0, c:"#DDD379", th:1}, | |
{n1:2, n2:5, se:1, c:"#DDD379", th:1}, | |
{n1:2, n2:6, se:0, c:"#DDD379", th:1}, | |
{n1:2, n2:7, se:1, c:"#DDD379", th:1}, | |
{n1:2, n2:8, se:1, c:"#DDD379", th:1}, | |
{n1:2, n2:9, se:0, c:"#DDD379", th:1}, | |
{n1:3, n2:6, se:0, c:"#DDD379", th:1}, | |
{n1:3, n2:7, se:1, c:"#DDD379", th:1}, | |
{n1:3, n2:8, se:0, c:"#DDD379", th:1}, | |
{n1:3, n2:9, se:1, c:"#DDD379", th:1} | |
], | |
nFlag:0 | |
},{ | |
name:'N', | |
nails:[ | |
{s:{x:250, y:460},e:{x:250, y:20},n:40}, | |
{s:{x:250, y:20},e:{x:710, y:460},n:40}, | |
{s:{x:710, y:460},e:{x:710, y:20},n:40} | |
], | |
strings:[ | |
{n1:0, n2:1, se:0, c:"#00ff87", th:2}, | |
{n1:1, n2:2, se:0, c:"#008cff", th:2} | |
], | |
nFlag:0 | |
},(function(){ | |
var a = d3.range(0,6).map(function(a){ return a*2*Math.PI/6;}); | |
var r = 260, cx=480, cy=240; | |
var ret ={name:'Twins',nails:[], strings:[],nFlag:0}; | |
ret.nails=a.map(function(a){ return {s:{x:cx, y:cy}, e:{x:cx+r*Math.cos(a), y:cy-r*Math.sin(a)},n:40};}); | |
ret.strings=[ | |
{n1:0, n2:2, se:1, c:"yellow", th:1}, | |
{n1:3, n2:5, se:1, c:"red", th:1}, | |
{n1:0, n2:4, se:1, c:"yellow", th:1}, | |
{n1:1, n2:3, se:1, c:"red", th:1} | |
]; | |
return ret; | |
})(),{ | |
name:'Rectangle', | |
nails:[ | |
{s:{x:10, y:10},e:{x:950, y:10},n:60}, | |
{s:{x:950, y:10},e:{x:950, y:470},n:60}, | |
{s:{x:950, y:470},e:{x:30, y:470},n:60}, | |
{s:{x:10, y:470},e:{x:10, y:10},n:60} | |
], | |
strings:[ | |
{n1:0, n2:1, se:0, c:"#fff", th:1}, | |
{n1:1, n2:2, se:0, c:"#fff", th:1}, | |
{n1:2, n2:3, se:0, c:"#fff", th:1}, | |
{n1:3, n2:0, se:0, c:"#fff", th:1} | |
], | |
nFlag:0 | |
},{ | |
name:'Square', | |
nails:[ | |
{s:{x:240, y:10},e:{x:470, y:10},n:30}, | |
{s:{x:470, y:10},e:{x:700, y:10},n:30}, | |
{s:{x:700, y:10},e:{x:700, y:240},n:30}, | |
{s:{x:700, y:240},e:{x:700, y:470},n:30}, | |
{s:{x:700, y:470},e:{x:470, y:470},n:30}, | |
{s:{x:470, y:470},e:{x:240, y:470},n:30}, | |
{s:{x:240, y:470},e:{x:240, y:240},n:30}, | |
{s:{x:240, y:240},e:{x:240, y:10},n:30}, | |
{s:{x:240, y:240},e:{x:470, y:240},n:30}, | |
{s:{x:470, y:10},e:{x:470, y:240},n:30}, | |
{s:{x:700, y:240},e:{x:470, y:240},n:30}, | |
{s:{x:470, y:470},e:{x:470, y:240},n:30} | |
], | |
strings:[ | |
{n1:7, n2:0, se:0, c:"#ff4100", th:1}, | |
{n1:1, n2:2, se:0, c:"#ff8e00", th:1}, | |
{n1:3, n2:4, se:0, c:"#00b25c", th:1}, | |
{n1:5, n2:6, se:0, c:"#0a67a3", th:1}, | |
{n1:8, n2:9, se:1, c:"#ff6c39", th:1}, | |
{n1:9, n2:10, se:1, c:"#ffa839", th:1}, | |
{n1:10, n2:11, se:1, c:"#29b773", th:1}, | |
{n1:11, n2:8, se:1, c:"#2e78a9", th:1} | |
], | |
nFlag:0 | |
},{ | |
name:'Square 2', | |
nails:[ | |
{s:{x:240, y:10},e:{x:470, y:10},n:30}, | |
{s:{x:470, y:10},e:{x:700, y:10},n:30}, | |
{s:{x:700, y:10},e:{x:700, y:240},n:30}, | |
{s:{x:700, y:240},e:{x:700, y:470},n:30}, | |
{s:{x:700, y:470},e:{x:470, y:470},n:30}, | |
{s:{x:470, y:470},e:{x:240, y:470},n:30}, | |
{s:{x:240, y:470},e:{x:240, y:240},n:30}, | |
{s:{x:240, y:240},e:{x:240, y:10},n:30}, | |
{s:{x:240, y:240},e:{x:400, y:240},n:30}, | |
{s:{x:470, y:10},e:{x:470, y:170},n:30}, | |
{s:{x:700, y:240},e:{x:540, y:240},n:30}, | |
{s:{x:470, y:470},e:{x:470, y:310},n:30} | |
], | |
strings:[ | |
{n1:7, n2:0, se:0, c:"#ff4100", th:1}, | |
{n1:1, n2:2, se:0, c:"#ff8e00", th:1}, | |
{n1:3, n2:4, se:0, c:"#00b25c", th:1}, | |
{n1:5, n2:6, se:0, c:"#0a67a3", th:1}, | |
{n1:8, n2:9, se:1, c:"#ff6c39", th:1}, | |
{n1:9, n2:10, se:1, c:"#ffa839", th:1}, | |
{n1:10, n2:11, se:1, c:"#29b773", th:1}, | |
{n1:11, n2:8, se:1, c:"#2e78a9", th:1} | |
], | |
nFlag:0 | |
} | |
]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment