我正在使用d3填充笛卡尔平面,其中一堆svg:image
个元素分布在不同的坐标上。
我想添加mouserover
和mouseout
逻辑,缩放鼠标所在的图像,并减轻其他人的不透明度。我在鼠标悬停时过滤我的选择只选择所需的元素,一切都很好,除了我的缩放逻辑似乎没有达到预期的效果。图像向下和向右扩展,而不是从对角线中心向外扩展。
这是我尝试过的:
transform: scale(1.5)
扩展,但也彻底改变了图像的位置transform: translate(-(width/2), -(height/2))
与scale结合使用,但是从不同的起始位置执行相同的操作对于我可以设置“锚点”来缩放的图像元素,是否没有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");
}
}
使用此方法,尽管大小相同,但图像会移动不一致的距离。
答案 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即可将其删除。
基本上,这只是将中心点转换为原点,围绕它缩放,并转换回正确的位置。请记住,变换以相反的顺序(从右到左)应用。
我认为你使用带缩放的平移是在正确的轨道上,但是从原点来回平移是允许它在原始位置保持居中的同时工作的。