d3 在转换中翻译旋转顺序
d3 translate rotate order in transition
我正在尝试使用 d3 转换 - 我需要同时进行平移和旋转。
我有原始坐标:
let data = [
{x: 100, y: 100, rotation: 45},
];
和 2 个矩形。一个是先平移,第二个是旋转
第一.
这是绘制矩形后的转换结果:
transform="rotate(45 115 105) translate(100, 100)"
transform="translate(100, 100) rotate(45 115 105)"
它们具有相同的平移和旋转变换,唯一不同的是它们的顺序。
那我改数据:
data[0].x += 30;
data[0].y += 20;
data[0].rotation += 45;
并且我希望通过这种转变得到一些转变:
transform="rotate(90 145 125) translate(130, 120)"
transform="translate(130, 120) rotate(90 145 125)"
但我真正得到的是:
transform="translate(150, 110) rotate(90)"
transform="translate(400, 100) rotate(90)"
- 注意它改变了第一个矩形的平移旋转顺序。
- 它还会从旋转变换中移除旋转中心(它会在转换过程中以某种方式计算它吗?)
- 它是如何得到结果数字的?
d3 转换是如何工作的?我需要获得一些预期的结果,因为我正在尝试进行一些更高级的转换。
这是一个简单的例子:https://jsfiddle.net/pp6npw4g/2
(点击移动开始转换)
这是 D3 对 transform
属性值的标准插值的预期行为。 transform
属性是出了名的难以转换,因为它的值可能包含一个复杂的转换定义列表,这些定义可能以任何顺序出现,甚至可能在一个列表中出现多次。例如:
transform="translate(100) rotate(30, 100, 100) scale(2.5) translate(-10, -50) skewX(20)"
为了能够在这些值之间转换,transition.attr()
function uses d3.interpolateTransformSvg(a, b)
在插入 transform
属性值时。这会执行以下操作:
内部函数parseSvg()
of module d3-interpolate the list of transform definitions is boiled down by calling .consolidate()
of interface SVGTransformList
.
使用私有函数 decompose()
然后将此合并转换分解为 translate、rotate[=56] 的值=]、倾斜和比例。
我已经在 to "Replacing d3.transform in D3 v4".
中描述了分解转换列表的过程
在过渡期间,d3.interpolateTransformSvg(a, b)
返回的插值器将在 a
和 b
的相应值之间插值,用于 (1) translate
、(2) rotate
、(3) skewX
和 (4) scale
正好在这个 order.
这给您留下了统一的价值观,乍一看,这似乎出乎意料。此外,它还解释了为什么转换顺序会因转换而改变。要解决此问题并实现自定义过渡,您必须提供自定义补间函数,该函数可以通过调用 transition.attrTween()
进行分配。不过,此功能的实现在很大程度上取决于您的需求,并且超出了此答案的范围。
我正在尝试使用 d3 转换 - 我需要同时进行平移和旋转。 我有原始坐标:
let data = [
{x: 100, y: 100, rotation: 45},
];
和 2 个矩形。一个是先平移,第二个是旋转 第一.
这是绘制矩形后的转换结果:
transform="rotate(45 115 105) translate(100, 100)"
transform="translate(100, 100) rotate(45 115 105)"
它们具有相同的平移和旋转变换,唯一不同的是它们的顺序。
那我改数据:
data[0].x += 30;
data[0].y += 20;
data[0].rotation += 45;
并且我希望通过这种转变得到一些转变:
transform="rotate(90 145 125) translate(130, 120)"
transform="translate(130, 120) rotate(90 145 125)"
但我真正得到的是:
transform="translate(150, 110) rotate(90)"
transform="translate(400, 100) rotate(90)"
- 注意它改变了第一个矩形的平移旋转顺序。
- 它还会从旋转变换中移除旋转中心(它会在转换过程中以某种方式计算它吗?)
- 它是如何得到结果数字的?
d3 转换是如何工作的?我需要获得一些预期的结果,因为我正在尝试进行一些更高级的转换。
这是一个简单的例子:https://jsfiddle.net/pp6npw4g/2 (点击移动开始转换)
这是 D3 对 transform
属性值的标准插值的预期行为。 transform
属性是出了名的难以转换,因为它的值可能包含一个复杂的转换定义列表,这些定义可能以任何顺序出现,甚至可能在一个列表中出现多次。例如:
transform="translate(100) rotate(30, 100, 100) scale(2.5) translate(-10, -50) skewX(20)"
为了能够在这些值之间转换,transition.attr()
function uses d3.interpolateTransformSvg(a, b)
在插入 transform
属性值时。这会执行以下操作:
内部函数
parseSvg()
of module d3-interpolate the list of transform definitions is boiled down by calling.consolidate()
of interfaceSVGTransformList
.使用私有函数
decompose()
然后将此合并转换分解为 translate、rotate[=56] 的值=]、倾斜和比例。
我已经在
在过渡期间,d3.interpolateTransformSvg(a, b)
返回的插值器将在 a
和 b
的相应值之间插值,用于 (1) translate
、(2) rotate
、(3) skewX
和 (4) scale
正好在这个 order.
这给您留下了统一的价值观,乍一看,这似乎出乎意料。此外,它还解释了为什么转换顺序会因转换而改变。要解决此问题并实现自定义过渡,您必须提供自定义补间函数,该函数可以通过调用 transition.attrTween()
进行分配。不过,此功能的实现在很大程度上取决于您的需求,并且超出了此答案的范围。