score:1

You are missing the `x` and `y` attributes of the `rect`. Since these give the top-left point, you can set the `rect` at the centre of the `svg` with:

``````// get centre of svg and rect width and height
var svgCentre = {x: width/ 2, y: height / 2};
var rectDims = {w: width / 5, h: height / 5};
var rect = g
.append("rect")
.attr("x", svgCentre.x - (rectDims.w / 2)) // offset left by half rect width
.attr("y", svgCentre.y - (rectDims.h / 2)) // offset up by half rect height
.attr("width", rectDims.w)
.attr("height", rectDims.h)
.style("fill", "white");
``````

Where `svgCentre` is half the width and half the height of the `svg`. Then you can offset the top-left point of the `rect` by half the width and half the height of the `rect`.

You mention you want to rotate the `rect` around the centre point - you can re-use the `svgCentre` coordinates in the `rotate` transform:

``````.attrTween("transform", () => {
var i = d3.interpolate(0, 360); // full circle
// set centre of rotation at centre of svg
return t => `rotate(\${i(t)}, \${svgCentre.x}, \${svgCentre.y})`;
});
``````

`attrTween` is figuring out that over the course of the transition you need to rotate through 360 degrees i.e. 5.55 degrees per millisecond. The `return t => ...` is saying return a function with an argument `t` which is some time in the `duration` that when passed to the `d3.interpolate` function (assigned to `i`) will resolve to the amount of degrees to rotate based on the time elapsed. This is then put into the string attribute of the `transform` for that moment in time.

Example:

``````const height = window.innerHeight - 20,
width = window.innerWidth - 20;

var body = d3
.select("body")
.style("text-align", "center")
.style("background", "#3c3c3c");

var svg = d3
.select("body")
.append("svg")
.attr("height", height)
.attr("width", width)
.style("background", "red")
.style("display", "inline-block");

var g = svg.append("g")

// get centre of svg and rect width and height
var svgCentre = {x: width/ 2, y: height / 2};
var rectDims = {w: width / 5, h: height / 5};
var rect = g
.append("rect")
.attr("x", svgCentre.x - (rectDims.w / 2)) // offset left by half rect width
.attr("y", svgCentre.y - (rectDims.h / 2)) // offset up by half rect height
.attr("width", rectDims.w)
.attr("height", rectDims.h)
.style("fill", "white")

// rotate rect through 360 degrees with centre of rotation at svg centre
rect.transition()
.duration(2000)
.attrTween("transform", () => {
var i = d3.interpolate(0, 360); // full circle
// set centre of rotation at centre of svg
return t => `rotate(\${i(t)}, \${svgCentre.x}, \${svgCentre.y})`;
});``````
``<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>``