Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active September 28, 2016 15:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nitaku/d6a766a92ce2ba88af4d19dfabc46f89 to your computer and use it in GitHub Desktop.
Save nitaku/d6a766a92ce2ba88af4d19dfabc46f89 to your computer and use it in GitHub Desktop.
Multihue Cushion Voronoi
svg = d3.select 'svg'
width = svg.node().getBoundingClientRect().width
height = svg.node().getBoundingClientRect().height
defs = svg.append 'defs'
radius = 10
sites_data = d3.range(20).map () ->
return {
x: Math.round(Math.random() * (width - radius * 2) + radius),
y: Math.round(Math.random() * (height - radius * 2) + radius)
}
voronoi = d3.voronoi()
.x (d) -> d.x
.y (d) -> d.y
.extent [[-1, -1], [width + 1, height + 1]]
cells_data = voronoi.polygons(sites_data)
# define cells gradients
gradients = defs.selectAll '.gradient'
.data sites_data
enter_gradients = gradients.enter().append 'radialGradient'
.attrs
class: 'gradient'
gradientUnits: 'userSpaceOnUse'
id: (d,i) -> "gradient_#{i}"
cx: (d) -> d.x
cy: (d) -> d.y
r: 300
enter_gradients.append 'stop'
.attrs
offset: '0%'
'stop-color': d3.hcl(80+0,40,100)
enter_gradients.append 'stop'
.attrs
offset: '25%'
'stop-color': d3.hcl(80+40,40,75)
enter_gradients.append 'stop'
.attrs
offset: '50%'
'stop-color': d3.hcl(80+80,40,50)
enter_gradients.append 'stop'
.attrs
offset: '75%'
'stop-color': d3.hcl(80+120,40,25)
enter_gradients.append 'stop'
.attrs
offset: '100%'
'stop-color': d3.hcl(80+160,40,0)
# render cells
cells = svg.selectAll '.cell'
.data cells_data
cells.enter().append 'path'
.attrs
class: 'cell'
d: (d) -> if not d? then null else "M" + d.join("L") + "Z"
fill: (d,i) -> "url(#gradient_#{i})"
# render sites
sites = svg.selectAll '.site'
.data sites_data
sites.enter().append 'circle'
.attrs
class: 'site'
r: radius
cx: (d) -> d.x
cy: (d) -> d.y
body, html {
padding: 0;
margin: 0;
height: 100%;
}
svg {
width: 100%;
height: 100%;
background: white;
}
.site {
fill: #DDD;
stroke: gray;
}
.cell {
shape-rendering: crispEdges;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Multihue Cushion Voronoi</title>
<link type="text/css" href="index.css" rel="stylesheet"/>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v0.4.min.js"></script>
</head>
<body>
<svg></svg>
<script src="index.js"></script>
</body>
</html>
// Generated by CoffeeScript 1.10.0
(function() {
var cells, cells_data, defs, enter_gradients, gradients, height, radius, sites, sites_data, svg, voronoi, width;
svg = d3.select('svg');
width = svg.node().getBoundingClientRect().width;
height = svg.node().getBoundingClientRect().height;
defs = svg.append('defs');
radius = 10;
sites_data = d3.range(20).map(function() {
return {
x: Math.round(Math.random() * (width - radius * 2) + radius),
y: Math.round(Math.random() * (height - radius * 2) + radius)
};
});
voronoi = d3.voronoi().x(function(d) {
return d.x;
}).y(function(d) {
return d.y;
}).extent([[-1, -1], [width + 1, height + 1]]);
cells_data = voronoi.polygons(sites_data);
gradients = defs.selectAll('.gradient').data(sites_data);
enter_gradients = gradients.enter().append('radialGradient').attrs({
"class": 'gradient',
gradientUnits: 'userSpaceOnUse',
id: function(d, i) {
return "gradient_" + i;
},
cx: function(d) {
return d.x;
},
cy: function(d) {
return d.y;
},
r: 300
});
enter_gradients.append('stop').attrs({
offset: '0%',
'stop-color': d3.hcl(80 + 0, 40, 100)
});
enter_gradients.append('stop').attrs({
offset: '25%',
'stop-color': d3.hcl(80 + 40, 40, 75)
});
enter_gradients.append('stop').attrs({
offset: '50%',
'stop-color': d3.hcl(80 + 80, 40, 50)
});
enter_gradients.append('stop').attrs({
offset: '75%',
'stop-color': d3.hcl(80 + 120, 40, 25)
});
enter_gradients.append('stop').attrs({
offset: '100%',
'stop-color': d3.hcl(80 + 160, 40, 0)
});
cells = svg.selectAll('.cell').data(cells_data);
cells.enter().append('path').attrs({
"class": 'cell',
d: function(d) {
if (d == null) {
return null;
} else {
return "M" + d.join("L") + "Z";
}
},
fill: function(d, i) {
return "url(#gradient_" + i + ")";
}
});
sites = svg.selectAll('.site').data(sites_data);
sites.enter().append('circle').attrs({
"class": 'site',
r: radius,
cx: function(d) {
return d.x;
},
cy: function(d) {
return d.y;
}
});
}).call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment