UNPKG

paper

Version:

The Swiss Army Knife of Vector Graphics Scripting

135 lines (125 loc) 4.58 kB
<!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>