|
<html> |
|
<head> |
|
<title>Cheap Sketchy</title> |
|
<meta charset="utf-8" /> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.min.js" charset="utf-8" type="text/javascript"></script> |
|
</head> |
|
<style> |
|
svg { |
|
height: 500px; |
|
width: 500px; |
|
border: 1px solid gray; |
|
} |
|
</style> |
|
<body> |
|
|
|
<div id="viz"> |
|
<svg class="main"> |
|
</svg> |
|
</div> |
|
</body> |
|
<footer> |
|
<script> |
|
|
|
//Create some shapes |
|
|
|
function cheapSketchy(path) { |
|
var length = path.getTotalLength(); |
|
var drawCode = ""; |
|
var i = 0; |
|
var step = 2; |
|
|
|
while (i < length / 2) { |
|
var start = path.getPointAtLength(i); |
|
var end = path.getPointAtLength(length - i); |
|
|
|
drawCode += " M" + (start.x + (Math.random() * step - step/2)) + " " + (start.y + (Math.random() * step - step/2)) + "L" + (end.x + (Math.random() * step - step/2)) + " " + (end.y + (Math.random() * step - step/2)); |
|
|
|
i += step + (Math.random() * step); |
|
} |
|
|
|
return drawCode; |
|
} |
|
|
|
function cheapSketchyOutline(path) { |
|
var j = 2; |
|
var i = 0; |
|
var length = path.getTotalLength(); |
|
var pointsArray = []; |
|
|
|
while (i < length) { |
|
newPoint = path.getPointAtLength(i); |
|
pointsArray.push({x: newPoint.x + (j/2 - Math.random() * j), y: newPoint.y + (j/2 - Math.random() * j)}); |
|
|
|
i += j + (Math.random() * (j)); |
|
} |
|
//Make sure to get the last point |
|
pointsArray.push(path.getPointAtLength(length)); |
|
|
|
var line = d3.svg.line() |
|
.x(function(d) { return d.x; }) |
|
.y(function(d) { return d.y; }) |
|
.interpolate("basis"); |
|
|
|
return line(pointsArray); |
|
} |
|
|
|
d3.select("svg").append("g") |
|
.attr("transform", "translate(50,50)") |
|
.datum("orange") |
|
.append("path").attr("d", "M 39.161481,0.33269981 C 23.836192,0.04604167 2.912469,6.6953575 0.19616865,24.750404 -3.3088936,48.048292 34.289385,59.946975 55.777303,57.949914 68.896857,56.730599 86.22939,44.922868 85.395921,31.773163 84.217,13.17323 57.795479,0.68124705 39.161481,0.33269981 z"); |
|
|
|
d3.select("svg").append("g") |
|
.attr("transform", "translate(150,50)") |
|
.datum("red") |
|
.append("path").attr("d", "M 31.795661,16.537504 8.871749,4.9948244 0.19616865,42.919427 33.750491,52.465257 50.375701,82.502648 89.724318,56.772845 67.226898,33.737382 73.454028,5.5027808 z"); |
|
|
|
d3.select("svg").append("g") |
|
.attr("transform", "translate(350,50)") |
|
.datum("blue") |
|
.append("path").attr("d", "M 44.072028,0.33269981 5.1067155,24.750404 C 36.091369,39.272988 70.224087,50.653364 39.572499,126.69757 L 81.467484,105.92242 C 100.86794,59.906873 85.538667,25.682721 44.072028,0.33269981 z"); |
|
|
|
d3.select("svg").selectAll("g > *") |
|
.attr("class", "original") |
|
.style("fill", function (d) {return d}).style("fill-opacity", 0.3); |
|
|
|
var drag = d3.behavior.drag().on("drag", resketch); |
|
|
|
d3.select("svg").selectAll("g").call(drag); |
|
|
|
d3.select("svg").selectAll("g").each(function (d) { |
|
var node = d3.select(this).select("*").node(); |
|
var fillCode = cheapSketchy(node); |
|
var strokeCode = cheapSketchyOutline(node); |
|
|
|
d3.select(this).append("path") |
|
.style("stroke-width", "1px") |
|
.style("stroke", d) |
|
.attr("class", "sketchy-fill") |
|
.attr("d", fillCode); |
|
|
|
d3.select(this).append("path") |
|
.style("stroke-width", "2px") |
|
.style("stroke", d) |
|
.style("fill", "none") |
|
.attr("class", "sketchy-stroke") |
|
.attr("d", strokeCode); |
|
}) |
|
|
|
resketch(); |
|
|
|
function resketch() { |
|
|
|
d3.select(this) |
|
.attr("transform", "translate(" + (d3.event.x - 50) + "," + (d3.event.y - 50) + ")"); |
|
|
|
var node = d3.select(this).select("path.original").node(); |
|
var fillCode = cheapSketchy(node); |
|
var strokeCode = cheapSketchyOutline(node); |
|
|
|
d3.select(this).select("path.sketchy-fill") |
|
.attr("d", fillCode); |
|
|
|
d3.select(this).select("path.sketchy-stroke") |
|
.attr("d", strokeCode); |
|
|
|
} |
|
|
|
|
|
</script> |
|
</footer> |
|
|
|
</html> |