Виновником здесь является сам D3, а не какая-либо спецификация SVG.
Проблема в том, что ваш переход использует d3.interpolateTransform
, как мы видим здесь :
var fullname = namespace(name), i = fullname === "transform" ? interpolateTransform : interpolate;
Это исходный код v4, а не v3, но принцип тот же, что и в действительном коде v3:
var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS);
Тогда, если мы посмотрим в исходном коде interpolateTransform
(опять v4, но v3 почти такой же), мы увидим, что он использует функцию с именем parseSvg
, которая вычисляет матрицу для нового преобразования:
function parseSvg(value) {
if (value == null) return identity;
if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
svgNode.setAttribute("transform", value);
if (!(value = svgNode.transform.baseVal.consolidate())) return identity;
value = value.matrix;
return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
}
Эта функция генерирует 0
как конечное значение в матрице, когда вы передаете ей rotate(360)
(фактическое значение равно -2.4492935982947064e-16
, что практически равно нулю).
Решение
Здесь есть несколько возможных решений, самое простое из которых - interpolateString
вместо interpolateTransform
.
Кроме того, поскольку ваш код использует D3 v3, вы можете воспользоваться d3.transform()
, который был удален в v4 / v5:
d3.interpolateString(d3.transform(d3.select(this).attr("transform")), "translate(100,100) rotate(360)")
Вот ваш код с этим изменением:
var svg = d3.select('svg');
var s = svg.append("rect")
.attr("width", 50)
.attr("height", 50)
.attr("x", -25)
.attr("y", -25)
.attr("fill", "red")
.attr("transform", "translate(100,100)");
s.transition()
.duration(1000)
.attr("transform", "translate(100,100) rotate(180)")
.transition()
.delay(1000)
.duration(1000)
.attrTween("transform", function() {
return d3.interpolateString(d3.transform(d3.select(this).attr("transform")), "translate(100,100) rotate(360)")
});
<svg></svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>