paper.js/examples/Rasters/PhyllotaxisRaster.html

99 lines
24 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Phyllotaxis Raster</title>
<link rel="stylesheet" href="../css/style.css">
<script type="text/javascript" src="../../dist/paper.js"></script>
<script type="text/paperscript" canvas="canvas">
// Example inspired by: 'Phyllotactic Spirals' by Ken Frederick
// http://scriptographer.org/scripts/general-scripts/phyllotactic-spirals/
// Further reading:
// http://en.wikipedia.org/wiki/Phyllotaxis
var raster;
var values = {
// The amount of paths to produce:
amount: 200
};
// Create a raster object, using the image
var raster = new Raster('sunflower');
// Transform the raster so it fills the bounding rectangle
// of the view:
raster.fitBounds(view.bounds, true);
// Hide the raster:
raster.visible = false;
// Create the group of circle shaped paths and scale it up a bit:
var group = createPhyllotaxis(values.amount);
group.scale(3);
function createPhyllotaxis(amount) {
var group = new Group();
// The Golden Angle (http://en.wikipedia.org/wiki/Golden_angle)
var rotation = 137.51;
var spacing = 5;
for (var i = 1; i <= amount; i++) {
var point = new Point({
length: spacing * Math.sqrt(i),
angle: i * rotation
});
var radius = 8 - (i / amount * 4);
var rectangleSize = new Size(0.95, 0.7) * radius;
var rectangle = new Rectangle(point, rectangleSize);
var cornerSize = new Size(radius / 4);
var path = new Path.RoundRectangle(rectangle, cornerSize);
path.rotate(i * rotation + 45);
group.addChild(path);
}
return group;
}
function colorizePaths() {
for (var i = 0, l = group.children.length; i < l; i++) {
var path = group.children[i];
// Set the path's fill color to the average color of the
// raster pixels that fall within it:
path.fillColor = raster.getAverageColor(path);
}
}
var position = view.center;
function onMouseMove(event) {
position = event.point;
}
// Whenever the window is resized, we need to fit the raster
// in the bounding rectangle of the view again:
function onResize() {
raster.fitBounds(view.bounds, true);
}
function onFrame(event) {
// 1/4th of the difference between the center position of
// the group and the current position of the mouse:
var delta = (position - group.position) / 4;
// If the length of the delta vector (the distance) is bigger
// than 1, reposition the group:
if (delta.length > 1)
group.position += delta;
// Rotate the group of paths by 1 degree:
group.rotate(1);
2011-05-19 12:42:03 -04:00
// Rotate each path in the group by 2 degrees:
for (var i = 0, l = group.children.length; i < l; i++) {
group.children[i].rotate(2);
}
// Colorize the paths every other frame:
if (event.count % 2 == 0) {
colorizePaths();
}
}
</script>
</head>
<body style="background:black">
<img width="415" height="492" id="sunflower" style="display: none;" src="data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAAOAAD/4QMraHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjAtYzA2MCA2MS4xMzQ3NzcsIDIwMTAvMDIvMTItMTc6MzI6MDAgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzUgTWFjaW50b3NoIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkUwOTE0MUU3N0E0NzExRTA5QTJDQzYxQjVCODAxRjgzIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkUwOTE0MUU4N0E0NzExRTA5QTJDQzYxQjVCODAxRjgzIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RTA5MTQxRTU3QTQ3MTFFMDlBMkNDNjFCNUI4MDFGODMiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RTA5MTQxRTY3QTQ3MTFFMDlBMkNDNjFCNUI4MDFGODMiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAATDw8YERgmFhYmMCQdJDAsJSQk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
<canvas id="canvas" resize></canvas>
2011-05-30 18:27:39 -04:00
</body>
</html>