2016-01-13 60 views
0

我有一個SVG形狀(這很複雜,我爲了理解而簡化了它),這是我需要轉換的。我的要求是,在SVG元素中保留一個變換

  1. 當鼠標懸停,集團的規模應以2倍
  2. 當鼠標移開,組應縮減爲1x
  3. 當拖動組規模應preseved

所以到目前爲止,除了一個問題,我已經設法完成了所有的部分。當我嘗試將鼠標懸停在組上時,它會將其恢復到其原始位置後拖動該元素。我不明白爲什麼會發生。這是一個工作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> 

的script.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 + ')'); 

       })) 

回答

1

正如@PhilAnderson所說,你不應該混合translatecx/cy。事實上,你嵌套元素的方式,你只應該翻譯。在SVG中翻譯您的g,然後在g內翻譯您的圈子。糾正,事情就變得簡單多了:

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script data-require="[email protected]" 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>

+0

這正是我想要的,TIP翻譯子元素的榮譽。這是我從未想到的。 – Fawzan

1

它看起來像你混淆了Cx和Cy與翻譯屬性。

在mouseenter和mouseleave中,根據cx和cy的值移動形狀,但在拖動事件中,只需使用事件的x和y值進行翻譯。

解決這個問題的一種方法是在你的拖動事件中設置cx和cy屬性,儘管tbh最好是解決一個方法並堅持到底。

+0

我的問題是我想要的組從圓心規模。你能不能友好地分享代碼示例? – Fawzan

+0

@ Mark的回答解決了問題並深入解釋了問題。早日澄清。 (y) – Fawzan