Javascript D3光标下没有SVG元素时的几何缩放
我正在实现几何缩放行为,如图所示 问题是,如果光标位于绿色覆盖矩形或任何其他SVG元素(直线、圆等)外的白点上,浏览器会截取鼠标滚轮事件并向下滚动页面 我希望能够自由缩放,不受我在可视化上的位置影响 下面是一个简单的重新创建问题的过程Javascript D3光标下没有SVG元素时的几何缩放,javascript,svg,d3.js,zooming,pan,Javascript,Svg,D3.js,Zooming,Pan,我正在实现几何缩放行为,如图所示 问题是,如果光标位于绿色覆盖矩形或任何其他SVG元素(直线、圆等)外的白点上,浏览器会截取鼠标滚轮事件并向下滚动页面 我希望能够自由缩放,不受我在可视化上的位置影响 下面是一个简单的重新创建问题的过程 var width = 300, height = 300; var randomX = d3.random.normal(width / 2, 80), randomY = d3.random.normal(height / 2, 80);
var width = 300,
height = 300;
var randomX = d3.random.normal(width / 2, 80),
randomY = d3.random.normal(height / 2, 80);
var data = d3.range(2000).map(function() {
return [
randomX(),
randomY()
];
});
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.call(d3.behavior.zoom().scaleExtent([-8, 8]).on("zoom", zoom))
.append("g");
svg.append("rect")
.attr("class", "overlay")
.attr("width", width)
.attr("height", height);
svg.selectAll("circle")
.data(data)
.enter().append("circle")
.attr("r", 2.5)
.attr("transform", function(d) { return "translate(" + d + ")"; });
function zoom() {
svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
在所有对象前面粘贴一个透明的矩形,这样鼠标事件就可以锁定。在SVG中,事件只发送到诸如RECT之类的渲染元素,而不发送到一般的未渲染背景
svg.append("rect")
.attr("fill", "none")
.attr("pointer-events", "all")
.attr("width", "100%")
.attr("height", "100%");
为了使其正常工作,SVG必须覆盖整个区域,以便获得与原始小提琴相同的外观,您需要将其剪裁到原始区域,这可以通过设置clipPath或(正如我在小提琴中所做的)创建一个Inser
元素来剪裁
var svg = d3.select("body").append("svg")
.attr("width", "100%")
.attr("height", "100%")
.call(d3.behavior.zoom().scaleExtent([-8, 8]).on("zoom", zoom));
svg = svg.append("svg")
.attr("width", width)
.attr("height", height)
在所有东西前面粘贴一个透明的矩形框,这样鼠标事件就可以锁定。在SVG中,事件只发送到诸如RECT之类的渲染元素,而不发送到一般的未渲染背景
svg.append("rect")
.attr("fill", "none")
.attr("pointer-events", "all")
.attr("width", "100%")
.attr("height", "100%");
为了使其正常工作,SVG必须覆盖整个区域,以便获得与原始小提琴相同的外观,您需要将其剪裁到原始区域,这可以通过设置clipPath或(正如我在小提琴中所做的)创建一个Inser
元素来剪裁
var svg = d3.select("body").append("svg")
.attr("width", "100%")
.attr("height", "100%")
.call(d3.behavior.zoom().scaleExtent([-8, 8]).on("zoom", zoom));
svg = svg.append("svg")
.attr("width", width)
.attr("height", height)
希望这不会太晚,我第一次错过了这个问题 它不能在Chrome下工作的原因是Chrome还没有在html元素上实现标准的CSS转换——尽管理解起来很奇怪,嵌入在网页中的SVG元素上最外层的
标记被视为用于布局的html元素
您有两个选择:
-webkit transform
:
有点神经质,因为您正在转换整个SVG并相应地重新调整页面布局。由于种种原因,我不明白CSS/webkit转换和SVG属性转换在应用于“innerSVG”元素时都不起作用
组元素,Chrome在转换该元素时没有问题:
希望这不会太晚,我第一次错过了这个问题 它不能在Chrome下工作的原因是Chrome还没有在html元素上实现标准的CSS转换——尽管理解起来很奇怪,嵌入在网页中的SVG元素上最外层的
标记被视为用于布局的html元素
您有两个选择:
-webkit transform
:
有点神经质,因为您正在转换整个SVG并相应地重新调整页面布局。由于种种原因,我不明白CSS/webkit转换和SVG属性转换在应用于“innerSVG”元素时都不起作用
组元素,Chrome在转换该元素时没有问题:
请使用fiddle..?在缩放处理程序中执行d3.event.preventDefault()中的代码代码>和
d3.event.stopPropagation()
@LarsKotthoff我尝试了你的建议,但问题似乎不是当我们在白色区域时缩放回调没有被调用;由于未调用缩放处理程序,因此代码无效。不过这是合乎逻辑的。@Manoj创建了一个简单的JSFIDLE,从本质上重新创建了这个问题(我的代码中有很多事情:))请将您尝试过的代码放在FIDLE中..?在缩放处理程序中执行d3.event.preventDefault()代码>和d3.event.stopPropagation()
@LarsKotthoff我尝试了你的建议,但问题似乎不是当我们在白色区域时缩放回调没有被调用;由于未调用缩放处理程序,因此代码无效。不过这是合乎逻辑的。@Manoj创建了一个简单的jsFiddle,从本质上重新创建了这个问题(我的代码中有很多东西:)。它确实适合我。我正在使用Firefox。我刚刚在Firefox下检查过,它可以正常工作;但不适用于Chrome。除了使用这种剪裁方法,没有其他方法了吗?我在问题中发布的图像是我想要使用它的实际场景,这种方法意味着丢失clipPath或内部SVG元素之外的任何内容。难道没有其他方法来实现这一点吗?我不明白为什么当我们在SVG画布上时d3没有得到缩放回调。它不转换或缩放。它被正确剪裁,但我无法与它交互。(没有缩放,也没有拖动)我的新版本更好了吗?没有,在Chrome下仍然一动不动。它确实适合我。我正在使用Firefox。我刚刚在Firefox下检查过,它可以正常工作;但不适用于Chrome。除了使用这种剪裁方法,没有其他方法了吗?我在问题中发布的图像是我想要使用它的实际场景,这种方法意味着丢失clipPath或内部SVG元素之外的任何内容。难道没有其他方法来实现这一点吗?我不明白为什么当我们在SVG画布上时d3没有得到缩放回调。它不转换或缩放。它被正确剪裁,但我无法与它交互。(没有缩放,也没有拖动)我的新版本更好了吗?没有,在Chrome下仍然静止不动。谢谢你,你的解决方案似乎解决了问题,而不需要妥协。谢谢你,你的解决方案似乎解决了问题,而不需要妥协。