如何获取 svg元素的比例
How to get the scale of a svgElement?
我正在研究svg。
<div id="wrap" style="transform: scale(2); width:300;height:300;">
<svg id="real" style="border:red 10px solid;" >
<rect/>
</svg>
</div>
var e = document.getElementById("real");
//an api to get scale from e directly ??
我的问题是,如何获得这个svgElement的规模?
我尝试了e.getCTM()
和e.getScreen()
.矩阵不包含刻度信息。
请给我一些建议。
另一个 SO 答案显示了如何使用 element.getBoundingClientRect().width / element.offsetWidth
获取元素相对于文档的比例。但是,svg
元素没有 offsetWidth
属性。因此,一种解决方案是临时将"offsetWidth-able"元素附加到svg
元素,例如div
,读取此临时助手上的比率,然后将其删除。如果插入的元素通过 CSS 应用了意外的比例转换(如代码片段所示),则此插入元素应直接应用transform: scale(1);
样式。
更新:当包含比例的 CSS 转换直接应用于svg
元素本身时,会出现进一步的复杂性。在这种情况下,需要解析样式,这可以使用getComputedStyle
和getPropertyValue
来完成,并从返回的矩阵字符串中提取小数位值。然后需要将其乘以前置div
的相对比例。
进一步更新:此解决方案目前似乎不适用于Safari,因为浏览器无法识别insertAdjacentHTML
尽管我可以找到的文档说它应该。(这是 Safari 错误还是我错过了什么?但是,该解决方案确实适用于Firefox和Chrome。
var e = document.getElementById("real");
var computedTransform = window.getComputedStyle(e).getPropertyValue("transform");
if (computedTransform === "none") {
eDirScale = 1;
} else {
var matrix = computedTransform.match(/matrix'(([^')]*)')/)[1].split(/, *| +/);
var scaleX = Math.sqrt(matrix[0] * matrix[0] + matrix[1] * matrix[1]);
var scaleY = Math.sqrt(matrix[2] * matrix[2] + matrix[3] * matrix[3]);
if (scaleX !== scaleY) throw "non-uniform scaling";
eDirScale = scaleX;
}
var eRelScale = e.getBoundingClientRect().width / e.offsetWidth;
e.insertAdjacentHTML('beforebegin', '<div id="temporaryPrepended" style="transform: scale(1)"></div>');
var prepended = document.getElementById("temporaryPrepended");
var pRelScale = prepended.getBoundingClientRect().width / prepended.offsetWidth;
prepended.parentNode.removeChild(prepended);
var scale = pRelScale * eDirScale;
document.write("<p>scale directly on 'svg': " + eDirScale + "</p>");
document.write("<p>scale on 'svg' relative to document: " + eRelScale + ", i.e. doesn't work in e.g. Firefox and, while it might work in Chrome (in Feb 2016), apparently won't in the near future</p>");
document.write("<p>scale on prepended 'div' relative to document: " + pRelScale + "</p>");
document.write("<p>total scale on 'svg' relative to document: " + scale + "</p>");
div {
transform: scale(4);
}
<div id="wrap" style="transform: scale(2); width:300;height:300;">
<svg id="real" style="transform: translate(10px, 10px) scale(1.5); border:red 10px solid; opacity: 0.3;" >
<rect/>
</svg>
</div>
当您运行上面的代码片段时,您可能需要在代码片段窗口中向下滚动或单击"整页"以查看结果。
是不可能的,或者更好地说"真正的元素没有被转换。如果它继承了变形,它将有效地缩放两次。
你会寻找getComputedStyle
,但它会告诉你同样的事情。作为参考,此处包含继承的属性:
var e = document.getElementById("real");
console.log(window.getComputedStyle(e)["transform"]);
console.log(window.getComputedStyle(e)["color"]);
<div id="wrap" style="transform: scale(2); color: blue; width:300; height:300;">
<svg id="real" style="border: red 10px solid;" >
<rect/>
</svg>
</div>
- 锚点元素不't使用svg时,请打开EDGE上的href
- 带有填充属性的SVG矩形显示在包含元素的上方插入框阴影
- 在select元素中显示highchart dashstyle(svg)
- 如何自动保存动态生成的HTML SVG元素
- 使用svg和javascript将一个类的元素动画化为另一个类
- 将包含SVG元素的HTML转换为图像文件
- SVG元素——处理和选择文本
- 更改SVG'style'元素
- SVG元素在转换后会丢失事件侦听器
- 获取以屏幕像素为单位的旋转SVG元素的边界
- 使用JavaScript查找具有特定属性的SVG元素
- 如何使用正则表达式按类获取svg元素
- d3与svg在处理元素时的对比
- 是否可以在不创建svg对象的情况下创建捕捉元素?[snap.svg]
- 将SVG元素拖动到另一个SVG元素上
- 捕捉.svg — 单击其中一个元素时删除对象
- 单击事件在替换<使用>元素在<svg>(Win7/IE11)
- 我想隐藏/显示我的SVG元素,同时在anguarJS中使用它
- 在元素 SVG 中使用 JavaScript 或 jQuery 进行事件单击
- 是否有一种方法可以使用Javascript合并两个路径元素(svg)