Skip to content

Instantly share code, notes, and snippets.

@kennelliott
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kennelliott/4749dddd8409aede8115 to your computer and use it in GitHub Desktop.
Save kennelliott/4749dddd8409aede8115 to your computer and use it in GitHub Desktop.
regular-polygons
<!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