d3.js svg image:从矩形中心缩放

时间:2014-01-31 16:20:39

标签: javascript svg d3.js scaling

我正在使用d3填充笛卡尔平面,其中一堆svg:image个元素分布在不同的坐标上。

我想添加mouserovermouseout逻辑,缩放鼠标所在的图像,并减轻其他人的不透明度。我在鼠标悬停时过滤我的选择只选择所需的元素,一切都很好,除了我的缩放逻辑似乎没有达到预期的效果。图像向下和向右扩展,而不是从对角线中心向外扩展。

这是我尝试过的:

  1. transform: scale(1.5)扩展,但也彻底改变了图像的位置
  2. transform: translate(-(width/2), -(height/2))与scale结合使用,但是从不同的起始位置执行相同的操作
  3. 将x和y坐标更改为调整为半宽和高度的坐标,具有相同的效果。
  4. 对于我可以设置“锚点”来缩放的图像元素,是否没有text-anchor等价物?我不确定html svg的说法是什么,但我想我正在考虑类似于很多矢量编辑器的锚点。

    当前方法,鼠标悬停处理程序:

      function fade(dir){
        return function(d){
          var others = svg.selectAll("image.movie_cover")
            .filter(function(g,i){
              return g != d
            })
            .transition().duration(800)
            .style("opacity",.3);
    
          var single = svg.selectAll("image.movie_cover")
            .filter(function(g,i){
              return g === d;
            })
            .transition().duration(900)
            .attr("transform", "translate(-40,-40) scale(1.4)")
    
            var title = keys[coords.indexOf(d)];
            var url = "/static/eshk/"+hash+"_images/" + title  + ".jpg";
    
            tt.transition()        
                    .duration(200)      
                    .style("opacity", .9);      
            tt.html(title)  
                  .style("left", (d3.event.pageX) + "px")     
                  .style("top", (d3.event.pageY - 28) + "px"); 
        }
     }
    

    使用此方法,尽管大小相同,但图像会移动不一致的距离。

2 个答案:

答案 0 :(得分:2)

设置:一个50 x 50的盒子,200,200。它需要转换为100 x 100.它更大更宽,所以需要向后移动25,例如175,175。更换硬编码具有在鼠标悬停时查找当前宽度的函数的值,以计算精确值。

d3.select('svg').append('rect');
rect = d3.select('rect');
rect.attr({
    height: 50,
    width: 50,
    x: 200,
    y: 200,
    color: 'steelblue'
})
.transition()
.attr({
    width: 100,
    height: 100,
    x: 175,
    y: 175
});

答案 1 :(得分:2)

这也可以在不修改宽度或位置属性的情况下完成:

                    images.on("mouseover", function(d, i) {
                    var selection = d3.select(this);
                    var offsetX = parseFloat(selection.attr("x"))+
                                  parseFloat(selection.attr("width")/2.0);
                    var offsetY = parseFloat(selection.attr("y"))+
                                  parseFloat(selection.attr("height")/2.0);
                    selection.attr({
                        transform:"translate("+offsetX+ ","+offsetY+") "+
                                  "scale(1.2) "+
                                  "translate(-"+offsetX+",-"+offsetY+ ")"
                    });
                });

在鼠标输出时,您只需将变换设置为null即可将其删除。

基本上,这只是将中心点转换为原点,围绕它缩放,并转换回正确的位置。请记住,变换以相反的顺序(从右到左)应用。

我认为你使用带缩放的平移是在正确的轨道上,但是从原点来回平移是允许它在原始位置保持居中的同时工作的。