首页 > 解决方案 > 在 d3 和 svg 中旋转后使用 path.getPointAtLength 获取点坐标

问题描述

我想在旋转路径后从路径中得到一些点

我使用下面的代码来旋转路径

let path= svg.append("path")
.attr("class","offset control")
.attr("d", lineFunction(offsetLineData))

.style("stroke-width", 0.5)
.style("stroke", "red")
.style("fill", "none")
.attr("transform","rotate(90,"+p.x+","+p.y+")")
.attr('transform-origin',"center")

然后我想得到路径的终点和起点

path.node().getPointAtLength(0)

但它在不旋转的地方返回协调我如何在旋转后获得点的 x 和 y

标签: d3.jssvg

解决方案


将 SVG 视为嵌套坐标系的树。每个元素都有自己的坐标,并通过如何重新​​计算它们的规则安装到其父元素中。这些规则可以是显式transform属性,也可以是和 的隐式组合width(“将框 A 放入大小 B”)。heightviewBox

transform属性被认为是到父元素的链接。这意味着,如果您要求元素的几何属性,大多数时候您会在应用转换之前获得值。应用后将要求父坐标系中的几何值。

由于这种复杂性,有几个 SVG API 函数可以找出这些坐标系如何组合在一起。在应用属性之前getPointAtLength()获取坐标。transform

var localPoint = path.node().getPointAtLength(0)

首先,您必须找出该transform属性的作用。这看起来有点复杂,部分原因是该属性可以设置动画并且可以包含函数列表,部分原因是 API 是……嗯……:

// construct a neutral matrix
var localMatrix = path.node().viewportElement.createSVGMatrix()
var localTransformList = path.node().transform.baseVal
 // is there at least one entry?
if (localTransformList.length) {
    // consolidate multiple entries into one
    localMatrix = localTransformList.consolidate().matrix
}

然后,您可以将找到的转换应用于该点

var transformedPoint = localPoint.matrixTransform(localMatrix)

应用属性后(即在上述步骤之后),有几个函数将返回 aSVGMatrix以从坐标系转换数据:transform

  • 要求转换到最近的视口(在大多数情况下是最近的父级<svg>)元素:element.getCTM()

  • 要求转换为屏幕像素: element.getScreenCTM()

  • 要求转换为任意元素: element.getTransformToElement(...)


推荐阅读