javascript - 在 SVG 元素中保留变换

标签 javascript d3.js svg

我有一个 SVG 形状(非常复杂,为了便于理解我将其变得简单),我需要对其进行转换。我的要求是,

  1. 当鼠标悬停时,该组应缩放至 2 倍
  2. 鼠标移开时,组应缩小至 1 倍
  3. 拖动时应保留组比例

到目前为止,除了一期外,我已经完成了所有部分。当我尝试将鼠标悬停在组上时拖动元素后,它会恢复到其原始位置。我不明白为什么会发生这种情况。这是一个工作fiddle 。谁能帮我吗?

index.html

<svg width="400" height="400" style="background-color: red">

    <g id="op" class="operator" transform="translate(0,0)">

        <circle class="head" cx="50" cy="50" r="20" style="fill: yellow"></circle>
        <circle cx="40" cy="40" r="10" style="fill: blue"></circle>
        <circle cx="60" cy="40" r="10" style="fill: blue"></circle>

    </g>

</svg>

脚本.js

d3.selectAll('.operator')
        .on('mouseenter', function () {

            console.log('Mouse Enter');
            var c = d3.select(this).select('.head');
            var x = c.attr('cx');
            var y = c.attr('cy');

            var scale = 2;
            var scaleX = -1 * x * (scale - 1);
            var scaleY = -1 * y * (scale - 1);

            d3.select(this).attr('transform', 'translate(' + scaleX + ',' + scaleY + ')' + 'scale(' + scale + ')');

        })
        .on('mouseleave', function () {

            console.log('Mouse Leave');
            var c = d3.select(this).select('.head');
            var x = c.attr('cx');
            var y = c.attr('cy');

            var scale = 1;
            var scaleX = -1 * x * (scale - 1);
            var scaleY = -1 * y * (scale - 1);

            d3.select(this).attr('transform', 'translate(' + scaleX + ',' + scaleY + ')' + 'scale(' + scale + ')');

        })
        .call(d3.behavior.drag()
                .origin(function () {

                    var t = d3.select(this);
                    return {
                        x: d3.transform(t.attr("transform")).translate[0],
                        y: d3.transform(t.attr("transform")).translate[1]
                    };
                })
                .on('drag', function () {

                    var oldScale = d3.transform(d3.select(this).attr('transform')).scale;

                    d3.select(this).attr('transform', 'translate(' + d3.event.x + ',' + d3.event.y + ')scale(' + oldScale + ')');

                }))

最佳答案

正如 @PhilAnderson 所说,您不应该混合 translatecx/cy。事实上,按照嵌套元素的方式,您应该只进行翻译。翻译 SVG 中的 g,然后翻译 g 中的圆圈。纠正这个问题,事情就变得简单多了:

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body>
  <svg width="400" height="400" style="background-color: red">
    <g id="op" class="operator" transform="translate(50,50)">
      <circle class="head" r="20" style="fill: yellow"></circle>
      <circle transform="translate(-10,0)" r="10" style="fill: blue"></circle>
      <circle transform="translate(10,0)" r="10" style="fill: blue"></circle>
    </g>
  </svg>
  <script>
    d3.select('.operator')
      .on('mouseenter', function() {

        console.log('Mouse Enter');
        
        var self = d3.select(this),
            xy = d3.transform(self.attr('transform')).translate,
            scale = 2;
        self.attr('transform', 'translate(' + xy[0] + ',' + xy[1] + ')' + 'scale(' + scale + ')');

      })
      .on('mouseleave', function() {

        console.log('Mouse Leave');
        var self = d3.select(this),
            xy = d3.transform(self.attr('transform')).translate,
            scale = 1;
            
        self.attr('transform', 'translate(' + xy[0] + ',' + xy[1] + ')' + 'scale(' + scale + ')');


      })
      .call(d3.behavior.drag()
        
        .on('drag', function() {
          
          var self = d3.select(this),
              oldScale = d3.transform(self.attr('transform')).scale;
          self.attr('transform', 'translate(' + d3.event.x + ',' + d3.event.y + ')scale(' + oldScale + ')');

        }))
  </script>
</body>

</html>

关于javascript - 在 SVG 元素中保留变换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34772401/

相关文章:

javascript - ember.js 备份/缓存 DOM 元素

javascript - html 文件无法从我的模板文件夹中运行

angular - 在 Angular 2 中解析 HTML 字符串并提取和更新值

javascript - 浏览器是否可以选择性地从网站请求资源?

javascript - 如何使用 Promise 查看 setTimeout 中错误的完整堆栈跟踪

javascript - 未捕获的类型错误 : Object [object Object] has no method 'editable'

javascript - 让条形图行在 D3 中显示不同转换率的任何方法

javascript - Jest mock 获取响应 blob 的 fetch() 函数

javascript - 使用 jQuery 内联 SVG 中的目标 id

JSF 在 SVG 之后吞下结束标记