See also the linear path tweening example.
xxxxxxxxxx
<meta charset="utf-8">
<style>
path {
fill: #ccc;
stroke: #000;
}
</style>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
<meta charset="utf-8">
<style>
path {
fill: #ccc;
stroke: #000;
}
</style>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
var width = 960,
height = 500
,d0="",d1="";
var projection = d3.geo.albers()
.rotate([120, 0])
.center([0, 37.7])
.scale(2700);
var coordinates0,coordinates1;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("california.json", function(polygon) {
coordinates0 = polygon.coordinates[0].map(projection);
coordinates1 = rectangle(coordinates0),
path = svg.append("path");
d0 = "M" + coordinates0.join("L") + "Z",
d1 = "M" + coordinates1.join("L") + "Z";
loop();
function loop() {
path
.attr("d", d0)
.transition()
.duration(1000)
.attr("d", d1)
.transition()
.delay(1000)
.attr("d", d0);
}
});
function rectangle(coordinates) {
var lengths = [length],
polygon = d3.geom.polygon(coordinates),
p0 = coordinates[0],
p1,
x,
y,
i = 0,
n = coordinates.length,
side = 0,
stepPerSide = n /4,
width=100,
height=140,rectangle = [];
var area = polygon.area();
var centroid = polygon.centroid(-1 / (6 * area));
console.log(centroid);
var x = centroid[0] + width/2;
var y = centroid[1] - height/2;
console.log(x,y);
rectangle.push([x,y]);
while (++i < n) {
if (side == 0) {
y = y + (height/stepPerSide);
} else if (side == 1) {
x = x - (width/stepPerSide);
} else if (side == 2) {
y = y - (height/stepPerSide);
} else {
x = x + (width/stepPerSide);
}
if (i > 0 && i % stepPerSide == 0) side++;
console.log(side);
rectangle.push([x,y])
}
console.log("STUFF",rectangle);
return rectangle;
}
function circle(coordinates) {
var circle = [],
length = 0,
lengths = [length],
polygon = d3.geom.polygon(coordinates),
p0 = coordinates[0],
p1,
x,
y,
i = 0,
n = coordinates.length;
// Compute the distances of each coordinate.
while (++i < n) {
p1 = coordinates[i];
x = p1[0] - p0[0];
y = p1[1] - p0[1];
lengths.push(length += Math.sqrt(x * x + y * y));
p0 = p1;
}
var area = polygon.area(),
radius = Math.sqrt(Math.abs(area) / Math.PI),
centroid = polygon.centroid(-1 / (6 * area)),
angleOffset = -Math.PI / 2, // TODO compute automatically
angle,
i = -1,
k = 2 * Math.PI / lengths[lengths.length - 1];
// Compute points along the circle’s circumference at equivalent distances.
while (++i < n) {
angle = angleOffset + lengths[i] * k;
circle.push([
centroid[0] + radius * Math.cos(angle),
centroid[1] + radius * Math.sin(angle)
]);
}
return circle;
}
</script>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js