Created
June 18, 2014 06:18
-
-
Save kpdecker/1f7603eea7c5f9b07243 to your computer and use it in GitHub Desktop.
Canvas Flower
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> | |
<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