Skip to content

Instantly share code, notes, and snippets.

@kpdecker
Created June 18, 2014 06:18
Show Gist options
  • Save kpdecker/1f7603eea7c5f9b07243 to your computer and use it in GitHub Desktop.
Save kpdecker/1f7603eea7c5f9b07243 to your computer and use it in GitHub Desktop.
Canvas Flower
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<canvas id="output" width="600" height="800"></canvas>
<script>
// Renderer code
var output = document.getElementById('output'),
context = output.getContext('2d');
var LIGHTS_PER_METER = 30;
var NUM_PIXELS = [
5,
10,
5, 1, 2, 1,
5, 1, 2, 1,
5, 1, 2, 1
].map(function(value) { return Math.floor(value * LIGHTS_PER_METER); });
var NUM_CIRCLES = 2,
NUM_LINES = NUM_PIXELS.length - NUM_CIRCLES,
FULL_CIRCLE = 2 * Math.PI,
PX_PER_METER = 150,
OUTER_RADIUS = 2,
OFFSET = OUTER_RADIUS*PX_PER_METER,
FOLD_RADIUS = 0.1,
ROTATE = Math.PI / 4.1;
function mapLine(line, pixelId) {
if (line < NUM_CIRCLES) {
// Circular components
var radius = 5*(line+1)/FULL_CIRCLE,
angle = FULL_CIRCLE * (pixelId / NUM_PIXELS[line]) + ROTATE;
return [radius*Math.cos(angle), radius*Math.sin(angle), 0];
} else {
var lineOffset = line - NUM_CIRCLES,
lineMod = lineOffset % 4,
// A bit of a hack here. We want o fold one of the lines slightly early
// to provide spacing between other objects displayed on the screen.
// If rotate is changed then the special casing here will need to be adjusted.
currentFold = lineOffset / 4 < 1 ? FOLD_RADIUS*1.8 : FOLD_RADIUS,
angle = FULL_CIRCLE * lineOffset / NUM_LINES + ROTATE,
radius = OUTER_RADIUS - pixelId / LIGHTS_PER_METER;
if (!lineMod && radius < currentFold) {
// Fake the depth for the components that are "folded over"
return [
currentFold*Math.cos(angle),
currentFold*Math.sin(angle) - radius + currentFold,
currentFold - radius
];
} else {
return [radius*Math.cos(angle), radius*Math.sin(angle), 0];
}
}
}
function lightPixel(line, pixel, color) {
var map = mapLine(line, pixel);
context.fillStyle = color;
context.fillRect(OFFSET + PX_PER_METER*map[0], OFFSET + PX_PER_METER*map[1], 2, 2);
}
</script>
<script>
// Example code
var COLORS = [
'#f00',
'#f00',
'#000', '#555', '#4f4', '#555',
'#000', '#555', '#4f4', '#555',
'#000', '#555', '#4f4', '#555',
];
for (var line = NUM_PIXELS.length; line; line--) {
for (var pixel = 0; pixel < NUM_PIXELS[line-1]; pixel++) {
lightPixel(line-1, pixel, COLORS[line-1]);
}
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment