【问题标题】:How to manipulate translate transforms on a SVG element with javascript in chrome?如何使用 chrome 中的 javascript 在 SVG 元素上操作翻译转换?
【发布时间】:2012-05-08 03:40:44
【问题描述】:

我想使用 JavaScript 操作 SVG 元素的 transform="translate(x,y)" 属性。

所以我得到了这个 HTML 代码:

<body>

<svg id="test" preserveAspectRatio="xMidYMid meet" viewBox="0 0 100% 100%" xmlns="http://www.w3.org/2000/svg" version="1.1">
    <rect transform="translate(100,100)" width="300" height="100" style="fill:rgb(0,0,255);stroke-width:1;stroke:rgb(0,0,0)" />
    <rect transform="translate(400,400)" width="300" height="400" style="fill:red; stroke-width:1; stroke: yellow" />
</svg>

</body>

还有这段 JavaScript 代码:

var positioner = (function(domUtils){

   var svg = document.getElementById("test");
   var elementOffset = 100;

   function getAbsoluteX(leftElement) {
    return domUtils.getWidth(leftElement) + elementOffset; 
   }

   function getAbsoluteY(topElement) {
    return domUtils.getHeight(topElement) + elementOffset;
   }   

   var rectangles = document.querySelectorAll("rect");
   for(var i = 0; i < rectangles.length; ++i) {
    var spaceLeft = 0;
    if(i > 0) {
      spaceLeft = getAbsoluteX(rectangles[i-1]);
    }
    var rect = rectangles[i];
    var attrValue = "translate(" + spaceLeft + ", 100)";
    rect.setAttribute('transform', attrValue);
   };
 })(domUtils);

其中getAbsoluteX()是自定义函数。

它在 Firefox 中运行良好,但在 chrome 中不行。任何人都知道解决方法或如何解决这个问题?

谢谢。 问候。

【问题讨论】:

  • 它对我来说很好用 (jsfiddle.net/un6ep)。 getAbsoluteX 方法有什么作用
  • 神秘.. 刚刚将其粘贴到jsfiddle.net/nfRGw 中,它工作正常。但是如果我离线尝试它,它就不起作用。也许 jsfiddle 使用了一些支持 Chrome 的框架?
  • viewBox="0 0 100% 100%" 看起来很不对

标签: javascript google-chrome svg transform


【解决方案1】:

在 Chrome、Firefox、IE 或任何不符合标准的 SVG 用户代理中,有两种方法可以获取/设置 SVG 元素的转换值:

通过属性处理转换

// Getting
var xforms = myElement.getAttribute('transform');
var parts  = /translate\(\s*([^\s,)]+)[ ,]([^\s,)]+)/.exec(xforms);
var firstX = parts[1],
    firstY = parts[2];

// Setting
myElement.setAttribute('transform','translate(30,100)');

优点:易于设置和理解(与标记相同)。
缺点:必须解析字符串值来找到你想要的;对于动画值,动画激活时不能要求基值;感觉很脏。

通过 SVG DOM 绑定处理转换

// Getting
var xforms = myElement.transform.baseVal; // An SVGTransformList
var firstXForm = xforms.getItem(0);       // An SVGTransform
if (firstXForm.type == SVGTransform.SVG_TRANSFORM_TRANSLATE){
  var firstX = firstXForm.matrix.e,
      firstY = firstXForm.matrix.f;
}

// Setting
myElement.transform.baseVal.getItem(0).setTranslate(30,100);

优点:无需尝试自己解析字符串;保留现有的转换列表(您可以查询或调整列表中的单个转换);你得到的是真正的值,而不是字符串。
缺点:起初可能会让人难以理解;更详细地设置简单值;没有从SVGTransform.matrix 中提取旋转、缩放或倾斜值的便捷方法,缺少browser support

您可能会发现我编写的用于探索 DOM 的工具对此很有帮助。

  1. 转到http://objjob.phrogz.net/svg/object/131
  2. 单击“显示继承的属性/方法?”复选框
  3. 看到 SVGRectElement 有一个 transform 属性,它是一个 SVGAnimatedTransformList
  4. 点击SVGAnimatedTransformList查看the properties and methods that object supports
  5. 探索!

【讨论】:

  • 如果您阅读了我的问题,那么您会发现我尝试使用您的第一个建议(通过属性)来设置值。但是,第一种或第二种方式在 Chrome 中都不起作用,但在 Firefox 中都可以正常工作。
  • @Daniel 我确实阅读了您的问题,并且我确信这两种方法在 Chrime 中都可以正常工作。你做错了什么——也许属性值字符串格式不正确——但是如果没有可重现的测试用例,我不能肯定地告诉你它是什么。
  • @DanielDinter 不是真的;没有getAbsoluteX 函数,我无法知道spaceLeft 被设置为"kittens!";我无法重现您的问题——您没有提供了可重现的测试用例——因此我无法进一步帮助您。对不起:/
  • 现在添加了完整的 javascript 部分。我认为函数getAbsoluteX 与解决问题无关,它只是返回任何整数值。你也可以写function getAbsoluteX() { return 100; } ...
  • 如果您只是将 xForms 重命名为转换,则可读性会更好。乍一看,有这样的变量名称令人困惑
【解决方案2】:

这是一个很老的问题,但如果您想知道,答案是 Chrome 不喜欢 translate(30, 100) - 它需要单位。它还更喜欢 -webkit-transform 用于 SVG。

【讨论】:

  • 想通过参考或示例来支持这一点吗?我按照您的建议尝试解决自己的问题,但没有运气。
  • 这一定是与 CSS 转换混淆了,它确实需要单位 - SVG 属性 transform 不需要。此外,逗号是多余的,它不会造成伤害,但translate(30 100) 也是合规的。
猜你喜欢
  • 1970-01-01
  • 2020-06-18
  • 2019-05-27
  • 2018-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-20
  • 1970-01-01
相关资源
最近更新 更多