Skip to content

Instantly share code, notes, and snippets.

@max-mapper
Created February 14, 2012 19:13
Show Gist options
  • Save max-mapper/1829359 to your computer and use it in GitHub Desktop.
Save max-mapper/1829359 to your computer and use it in GitHub Desktop.
valentines day hearts with d3
<!DOCTYPE html>
<html>
<head>
<title>happy valentines day</title>
<link href='http://fonts.googleapis.com/css?family=Lato:100,900' rel='stylesheet' type='text/css'>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?1.26.0"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.geo.js?1.26.0"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.geom.js?1.26.0"></script>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.js?1.26.0"></script>
<style type="text/css">
html { background: #FDADB6; text-align: center; }
/* this is kind of poetic */
.hearts { position: absolute; }
.skewed {
z-index: -1;
display: inline-block;
color: #fff;
font: 100 10em "lato";
letter-spacing: -2px;
text-transform: uppercase;
position: relative;
-webkit-transform: rotate(10deg) skew(10deg, 0);
-moz-transform: rotate(10deg) skew(10deg, 0);
-ms-transform: rotate(10deg) skew(10deg, 0);
-o-transform: rotate(10deg) skew(10deg, 0);
transform: rotate(10deg) skew(10deg, 0);
}
.skewed:after {
border-radius: .25em 0 0 .25em;
left: -2.5em;
}
.skewed:before {
border-radius: 0 .25em .25em 0;
right: -2.5em;
}
.skewed span {
position: relative;
text-shadow: 1px 2px 0 #666,
2px 3px 0 #888;
text-transform: uppercase;
}
path {
fill: salmon;
fill-opacity: .8;
stroke: #fff;
stroke-width: 1.5px;
}
line {
stroke: #999;
}
</style>
</head>
<body>
<div class="hearts"></div>
<h1 class="skewed"><span>happy valentines day!</span></h1>
<script type="text/javascript">
var w = window.innerWidth,
h = window.innerHeight;
var path = d3.geo.path(),
force = d3.layout.force().size([w, h]),
proj = d3.geo.albers()
.origin([-122.2711137, 37.8043637])
.parallels([37,38])
proj.scale(500000)
path.projection(proj)
var svg = d3.select(".hearts").append("svg:svg")
.attr("width", w)
.attr("height", h);
var hearts = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "01",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-122.23727200958211,
37.811798331614
],
[
-122.2402450115083,
37.808845549358225
],
[
-122.23608280881166,
37.79924819154948
],
[
-122.22690897429675,
37.7929387595257
],
[
-122.21798996851827,
37.79931531026993
],
[
-122.21229879340251,
37.80837577765766
],
[
-122.21493202367995,
37.81119436303169
],
[
-122.2213876850053,
37.811597009302176
],
[
-122.22605954517495,
37.80582553627838
],
[
-122.23124106281766,
37.81173122423769
],
[
-122.23727200958211,
37.811798331614
]
]
]
}
},
{
"type": "Feature",
"id": "01",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-122.26970011855468,
37.78726519172574
],
[
-122.26446444655761,
37.78828265331421
],
[
-122.26043040419921,
37.78512847679116
],
[
-122.25819880629882,
37.781974165645735
],
[
-122.25579554702148,
37.78458580919286
],
[
-122.25090319777831,
37.78689211896655
],
[
-122.24592501784667,
37.785365892612504
],
[
-122.24824244643554,
37.780278243794726
],
[
-122.25304896499023,
37.77413868131639
],
[
-122.25914294387206,
37.769966201472144
],
[
-122.26497943068847,
37.77468142561567
],
[
-122.26944262648925,
37.78075310583526
],
[
-122.26970011855468,
37.78726519172574
]
]
]
}
}
]
}
var nodes = [],
links = [];
hearts.features.forEach(function(d, i) {
var centroid = path.centroid(d);
centroid.x = centroid[0];
centroid.y = centroid[1];
centroid.feature = d;
nodes.push(centroid);
});
d3.geom.delaunay(nodes).forEach(function(d) {
links.push(edge(d[0], d[1]));
links.push(edge(d[1], d[2]));
links.push(edge(d[2], d[0]));
});
force
.gravity(0)
.nodes(nodes)
.links(links)
.linkDistance(function(d) { return d.distance; })
.start();
var link = svg.selectAll("line")
.data(links)
.enter().append("svg:line")
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
var node = svg.selectAll("g")
.data(nodes)
.enter().append("svg:g")
.attr("transform", function(d) { return "translate(" + -d.x + "," + -d.y + ")"; })
.call(force.drag)
.append("svg:path")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.attr("d", function(d) { return path(d.feature); });
force.on("tick", function(e) {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
});
function edge(a, b) {
var dx = a[0] - b[0], dy = a[1] - b[1];
return {
source: a,
target: b,
distance: Math.sqrt(dx * dx + dy * dy)
};
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment