javascript - d3 在转换中翻译旋转顺序

标签 javascript d3.js svg 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()函数使用 d3.interpolateTransformSvg(a, b)在插入 transform 属性值时。这会执行以下操作:

  1. 内部函数内parseSvg()模块 d3-interpolate 的转换定义列表通过调用接口(interface) SVGTransformList.consolidate() 进行归结。 .

  2. 使用私有(private)函数 decompose()然后将此合并转换分解为平移旋转倾斜缩放 的值。

我在 answer 中描述了分解转换列表的过程。至 "Replacing d3.transform in D3 v4" .

在过渡期间,d3.interpolateTransformSvg(a, b) 返回的插值器将在 ab 的相应值之间进行插值对于 (1) translate、(2) rotate、(3) skewX 和 (4) scale这个order .

这给您留下了统一的值(value)观,乍一看,这似乎出乎意料。此外,它还解释了为什么转换顺序会因转换而改变。要解决此问题并实现自定义转换,您必须提供自定义补间函数,可以通过调用 transition.attrTween() 来分配该函数。 .不过,此功能的实现在很大程度上取决于您的需求,并且超出了本答案的范围。

关于javascript - d3 在转换中翻译旋转顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41407217/

相关文章:

css - 在 feColorMatrix 滤镜中匹配颜色

javascript - 使用 Lodash 将数组转换为嵌套对象,这可能吗?

javascript - 如何避免在 D3 中对颜色进行硬编码

css - 在 CSS 3 中用圆弧绘制圆

d3.js - d3.js 中力图链接上的节点

javascript - 热图按日期隐藏列

css - 如何将 360 滚动到 svg 组的中心?

javascript - 如何部分更新 DynamoDB 表?

javascript - 无法将消息发布到文件 ://. 收件人在 Cordova WKWebView 引擎页面上的来源为空

javascript - 如何在对象的属性值中引用 'this'?