paper.js/examples/Paperjs.org/Voronoi.html

134 lines
4.5 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Voronoi</title>
<link rel="stylesheet" href="../css/style.css">
<script type="text/javascript" src="../../dist/paper-full.js"></script>
<script type="text/javascript" src="http://paperjs.org/assets/js/rhill-voronoi-core.js"></script>
<script type="text/paperscript" canvas="canvas">
var voronoi = new Voronoi();
var sites = generateBeeHivePoints(view.size / 200, true);
var bbox, diagram;
var oldSize = view.size;
var spotColor = new Color('red');
var mousePos = view.center;
var selected = false;
onResize();
function onMouseDown(event) {
sites.push(event.point);
renderDiagram();
}
function onMouseMove(event) {
mousePos = event.point;
if (event.count == 0)
sites.push(event.point);
sites[sites.length - 1] = event.point;
renderDiagram();
}
function renderDiagram() {
project.activeLayer.removeChildren();
var diagram = voronoi.compute(sites, bbox);
if (diagram) {
for (var i = 0, l = sites.length; i < l; i++) {
var cell = diagram.cells[sites[i].voronoiId];
if (cell) {
var halfedges = cell.halfedges,
length = halfedges.length;
if (length > 2) {
var points = [];
for (var j = 0; j < length; j++) {
v = halfedges[j].getEndpoint();
points.push(new Point(v));
}
createPath(points, sites[i]);
}
}
}
}
}
function removeSmallBits(path) {
var averageLength = path.length / path.segments.length;
var min = path.length / 50;
for (var i = path.segments.length - 1; i >= 0; i--) {
var segment = path.segments[i];
var cur = segment.point;
var nextSegment = segment.next;
var next = nextSegment.point + nextSegment.handleIn;
if (cur.getDistance(next) < min) {
segment.remove();
}
}
}
function generateBeeHivePoints(size, loose) {
var points = [];
var col = view.size / size;
for (var i = -1; i < size.width + 1; i++) {
for (var j = -1; j < size.height + 1; j++) {
var point = new Point(i, j) / new Point(size) * view.size + col / 2;
if (j % 2)
point += new Point(col.width / 2, 0);
if (loose)
point += (col / 4) * Point.random() - col / 4;
points.push(point);
}
}
return points;
}
function createPath(points, center) {
var path = new Path();
if (!selected) {
path.fillColor = spotColor;
} else {
path.fullySelected = selected;
}
path.closed = true;
for (var i = 0, l = points.length; i < l; i++) {
var point = points[i];
var next = points[(i + 1) == points.length ? 0 : i + 1];
var vector = (next - point) / 2;
path.add({
point: point + vector,
handleIn: -vector,
handleOut: vector
});
}
path.scale(0.95);
removeSmallBits(path);
return path;
}
function onResize() {
var margin = 20;
bbox = {
xl: margin,
xr: view.bounds.width - margin,
yt: margin,
yb: view.bounds.height - margin
};
for (var i = 0, l = sites.length; i < l; i++) {
sites[i] = sites[i] * view.size / oldSize;
}
oldSize = view.size;
renderDiagram();
}
function onKeyDown(event) {
if (event.key == 'space') {
selected = !selected;
renderDiagram();
}
}
</script>
</head>
<body>
<canvas id="canvas" resize></canvas>
</body>
</html>