Last active
August 29, 2015 14:02
-
-
Save kennelliott/4749dddd8409aede8115 to your computer and use it in GitHub Desktop.
regular-polygons
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> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>regular polygons</title> | |
<style type="text/css"> | |
body { | |
margin: 0; | |
font-size: 10px; | |
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; | |
} | |
.shell { | |
min-height: 500px; | |
padding: 20px 60px; | |
background-color: #bfe0e2; | |
color: #505050; | |
} | |
#error { | |
height: 18px; | |
margin: 0 0 14px 0; | |
color: #f65b36; | |
font-size: 1.4em; | |
font-family: Georgia, 'Helvetica Neue', Helvetica, Arial, sans-serif; | |
font-style: italic; | |
line-height: 1.3em; | |
text-align: center; | |
} | |
.inputs { | |
width: 424px; | |
margin: 0 auto 30px auto; | |
} | |
input[type=text] { | |
float: left; | |
width: 200px; | |
height: 60px; | |
border: none; | |
border-bottom: 4px solid #5db5b3; | |
background-color: rgba(255, 255, 255, .6); | |
color: inherit; | |
font-size: 5em;; | |
font-family: inherit; | |
text-align: center; | |
} | |
input[type=text]:focus { | |
outline: none; | |
} | |
input[name=sides] { | |
margin-right: 20px; | |
} | |
.input-labels p { | |
float: left; | |
width: 200px; | |
margin: 8px 0 20px 0; | |
color: #5db5b3; | |
font-size: 2.2em; | |
text-align: center; | |
} | |
.input-labels p:first-child { | |
margin-right: 20px; | |
} | |
#pie { | |
clear: both; | |
width: 140px; | |
margin: 0 auto; | |
padding: 8px 0; | |
background-color: #5db5b3; | |
color: #bfe0e2; | |
font-size: 1.4em; | |
text-align: center; | |
cursor: pointer; | |
visibility: hidden; | |
} | |
#polygon { | |
clear: both; | |
margin: 0 auto; | |
} | |
.path-polygon { | |
fill: #2f283b; | |
} | |
.path-pie { | |
fill: none; | |
stroke: #bfe0e2; | |
stroke-width: 2; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="shell"> | |
<div class="inputs"> | |
<p id="error"></p> | |
<form> | |
<input type="text" id="sides" name="sides"> | |
<input type="text" id="size" name="size"> | |
</form> | |
<div class="input-labels"> | |
<p>number of sides</p> | |
<p>size, in pixels</p> | |
</div> | |
<p id="pie">make me a pie</p> | |
</div> | |
<div id="polygon"></div> | |
</div> | |
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
<script type="text/javascript"> | |
var poly = document.getElementById('polygon'), | |
svg = d3.select('#polygon').append('svg'), | |
inputs = document.getElementsByTagName('input'), | |
error = document.getElementById('error'), | |
pie = document.getElementById('pie'), | |
vertices, | |
selection = {}, | |
errors = [ | |
'', | |
'more than two sides, please.', | |
'numbers only, please. no funny business' | |
]; | |
var line = d3.svg.line() | |
.x(function(d) { return d[0]; }) | |
.y(function(d) { return d[1]; }) | |
.interpolate('linear'); | |
var makePolygon = function(num_sides) { | |
var returned = function(polygon_size) { | |
drawPolygon(num_sides, polygon_size); | |
}; | |
return returned; | |
}; | |
var drawPolygon = function(sides, size) { | |
var r = size / 2, | |
c = [r, r], | |
a = 360 / sides; | |
vertices = getVertices(sides, a, r); | |
svg.attr('width', size) | |
.attr('height', size) | |
.append('g'); | |
svg.append('path') | |
.datum(vertices) | |
.attr('class', 'path-polygon') | |
.attr('d', line); | |
}; | |
var getVertices = function(sides, angle, radius) { | |
var v = [], | |
closure; | |
for (var i = 0; i < sides; i += 1) { | |
var this_angle = angle * i, | |
radian = convertToRadians(this_angle), | |
x_coord = getXCoord(radian, radius) + radius, | |
y_coord = getYCoord(radian, radius) + radius, | |
coord = [x_coord, y_coord]; | |
v.push(coord); | |
} | |
closure = v[0]; | |
v.push(closure); | |
return v; | |
}; | |
var convertToRadians = function(degrees) { | |
var radians = (degrees * Math.PI) / 180; | |
return radians; | |
}; | |
var getXCoord = function(angle, radius) { | |
var coord = Math.cos(angle) * radius, | |
coord_round = Math.round(coord); | |
return coord_round; | |
}; | |
var getYCoord = function(angle, radius) { | |
var coord = Math.sin(angle) * radius, | |
coord_round = Math.round(coord); | |
return coord_round; | |
}; | |
var rejectSelection = function(obj, field_val, error_index, id) { | |
handleValue(obj, field_val, error_index); | |
delete selection[id]; | |
pie.style.visibility = 'hidden'; | |
}; | |
var handleValue = function(obj, field_val, error_index) { | |
obj.value = field_val; | |
error.textContent = errors[error_index]; | |
svg.html(''); | |
}; | |
var checkSelection = function() { | |
var counter = 0; | |
for (var key in selection) { | |
counter += 1; | |
} | |
if (counter === 2) { | |
var sides = selection.sides, | |
size = selection.size, | |
poly = makePolygon(sides); | |
pie.style.visibility = 'visible'; | |
poly(size); | |
centerPoly(size); | |
} | |
}; | |
var centerPoly = function(width) { | |
poly.style.width = width + 'px'; | |
}; | |
for (var i = 0; i < inputs.length; i += 1) { | |
inputs[i].addEventListener('change', function() { | |
var id = this.id, | |
checked_val = parseInt(this.value, 10); | |
if (isNaN(checked_val)) { | |
rejectSelection(this, '', 2, id); | |
} else if (checked_val < 3 && id === 'sides') { | |
rejectSelection(this, '', 1, id); | |
} else { | |
handleValue(this, checked_val, 0); | |
selection[id] = checked_val; | |
checkSelection(); | |
} | |
}); | |
} | |
document.getElementById('pie') | |
.addEventListener('click', function() { | |
var v = vertices.slice(0, -1); | |
v.forEach(function(d, i) { | |
var w = selection.size, | |
r = w / 2, | |
coords = [[r, r], d]; | |
svg.append('path') | |
.datum(coords) | |
.attr('class', 'path-pie') | |
.attr('d', line); | |
}); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment