Edit in JSFiddle

// Parameters.

// Canvas dimensions
var width = 500;
var height = 500;

// Animation parameters
var angleCycle = 90;
var animateLength = 1000; // Milliseconds

// Shape parameters
var count = 5;
var shape = "-50 0, 50 -50, 50 50"; // SVG coordinates

///////////////////////////////////////////////////////////////////////////////

var centerX = width / 2;
var centerY = height / 2;
var radius = Math.min(width / 2, height / 2) / 2;

// Eschew needless annoying string concatenation.
function translate(x, y)
	{return "translate(" + x + "," + y + ")";}
function rotate(angle)
    {return "rotate(" + angle + ")";}
function rotateAroundPoint(angle, x, y)
	{return "rotate(" + angle + "," + x + ", " + y + ")";}

// Convert the index of an element to an angle on a circle.
function toRadians(i)
{
    var tau = 2 * Math.PI;
    var ratio = i / count;
    return tau * ratio;
}
function toDegrees(i)
{
    var degrees = 360;
    var ratio = i / count;
    return degrees * ratio;
}

// Determine the output X and Y coordinates relative to (0, 0) of its parent.
function getX(i)
	{return radius * Math.cos(toRadians(i));} // centerX
function getY(i)
	{return radius * Math.sin(toRadians(i));} // centerY
function getOppositeX(i)
	{return - radius * Math.cos(toRadians(i));} // centerX
function getOppositeY(i)
	{return - radius * Math.sin(toRadians(i));} // centerY

///////////////////////////////////////////////////////////////////////////////

// Generate the graphics:

// Create a dummy array to 'store' each shape.
var data = new Array(count);
// Create the canvas to place our images.
var svg = d3.select("body").append("svg")
	.attr("width", width)
	.attr("height", height)
	;
// Create a group selection to center and rotate the shapes.
var all = svg.append("g")
	.attr("transform", translate(centerX, centerY));

// Creates a data join selection (this is the confusing part).
var join = all.selectAll("g").data(data);
// For every element that was passed into data(), we do the following things:
var gEnter = join.enter()
	// Create a sub-group and place it accordingly around the center.
	.append("g")
	.attr("transform", function(d, i)
		{
    		var t = translate(getX(i), getY(i));
    		var r = rotateAroundPoint(toDegrees(i), 0, 0);
    		return t + r;
		})
	;
// Create the shape corresponding to the group.
var pEnter = gEnter
    .append("polygon")
	.attr("points", shape)
	;

// Animate the shapes, rotating the canvas as an offset of the previous animation.
function animateForward(prevAngle)
{
    // newAngle will overflow after a long time, but I don't think we should worry about that.
    var newAngle = prevAngle + angleCycle;
    
    // Rotate the entire image.
    all.transition().duration(animateLength)
        .attr("transform", translate(centerX, centerY) + rotate(newAngle))
    	// Mutually recursive call to animateBackward
        .each("end", function(){animateBackward(newAngle);})
        ;
	// Move each shape to the opposite side of the circle.
    join.transition().duration(animateLength)
        .attr("transform", function(d, i)
              {
                var transforms = d3.transform(d3.select(this).attr("transform"));
                var t = translate(getOppositeX(i), getOppositeY(i));
                var r = rotateAroundPoint(transforms.rotate, 0, 0);
                return t + r;
            })
        ;
}

function animateBackward(prevAngle)
{
    var newAngle = prevAngle + angleCycle;
    
    // Rotate the entire image.
    all.transition().duration(animateLength)
        .attr("transform", translate(centerX, centerY) + rotate(newAngle))
    	// Mutually recursive call to animateForward
        .each("end", function(){animateForward(newAngle);})
        ;
	// Move each shape to the original side of the circle.
    join.transition().duration(animateLength)
        .attr("transform", function(d, i)
              {
                var transforms = d3.transform(d3.select(this).attr("transform"));
                var t = translate(getX(i), getY(i));
                var r = rotateAroundPoint(transforms.rotate, 0, 0);
                return t + r;
            })
        ;
}

// Run the animation.
animateForward(0);