Javascript SVG放大鼠标-数学模型
在您思考“为什么这个家伙在这个问题上寻求帮助,这肯定已经实现了1000x”之前,虽然您基本上是正确的,但我已经尝试用几个开源lib来解决这个问题 我试图从头开始实现一个基于SVG的“放大鼠标滚轮,聚焦鼠标” 我知道有很多库可以实现这一点,d3和svg平移缩放就是其中之一。不幸的是,我使用这些lib的实现没有达到我的预期。我希望我能从社区那里得到一些帮助,为这种类型的UI特性建立基本的数学模型 基本上,所需的行为类似于谷歌地图,用户将鼠标悬停在某个位置上,滚动鼠标滚轮(向内),地图图像的比例增加,而悬停的位置成为视口的水平和垂直中心 当然,我可以访问视口的宽度/高度和鼠标的x/y 在本例中,我将仅关注x轴,视口宽度为900单位,正方形宽度为100单位,其x偏移为400单位,比例为1:1Javascript SVG放大鼠标-数学模型,javascript,css,svg,Javascript,Css,Svg,在您思考“为什么这个家伙在这个问题上寻求帮助,这肯定已经实现了1000x”之前,虽然您基本上是正确的,但我已经尝试用几个开源lib来解决这个问题 我试图从头开始实现一个基于SVG的“放大鼠标滚轮,聚焦鼠标” 我知道有很多库可以实现这一点,d3和svg平移缩放就是其中之一。不幸的是,我使用这些lib的实现没有达到我的预期。我希望我能从社区那里得到一些帮助,为这种类型的UI特性建立基本的数学模型 基本上,所需的行为类似于谷歌地图,用户将鼠标悬停在某个位置上,滚动鼠标滚轮(向内),地图图像的比例增加,
<g transform="translate(0 0) scale(1)">
假设鼠标x的位置是450个单位或接近450个单位,如果用户旋转直到比例达到2:1,我希望x偏移达到-450个单位,像这样将焦点居中
<g transform="translate(-450 0) scale(2)">
需要根据当前缩放/鼠标偏移,在滚轮滚动的每个增量上重新计算x和y偏移
我所有的尝试都完全没有达到预期的效果,任何建议都很感激
虽然我很感谢您的帮助,但请不要回答第三方库、jQuery插件和类似的问题。我的目标是从一般意义上理解这个问题背后的数学模型,我使用SVG主要是为了说明。我通常做的是维护三个变量的偏移量x偏移量y和比例。它们将作为转换应用于容器组,就像您的元素
如果鼠标位于原点上方,则新的平移计算起来就微不足道了。只需将偏移量x和y乘以比例差:
offsetX = offsetX * newScale/scale
offsetY = offsetY * newScale/scale
可以做的是平移偏移,使鼠标位于原点。然后你缩放,然后你把所有的东西都翻译回来。看看这个typescript类,它有一个scaleRelativeTo方法来完成您想要的任务:
export class Point implements Interfaces.IPoint {
x: number;
y: number;
public constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
add(p: Interfaces.IPoint): Point {
return new Point(this.x + p.x, this.y + p.y);
}
snapTo(gridX: number, gridY: number): Point {
var x = Math.round(this.x / gridX) * gridX;
var y = Math.round(this.y / gridY) * gridY;
return new Point(x, y);
}
scale(factor: number): Point {
return new Point(this.x * factor, this.y * factor);
}
scaleRelativeTo(point: Interfaces.IPoint, factor: number): Point {
return this.subtract(point).scale(factor).add(point);
}
subtract(p: Interfaces.IPoint): Point {
return new Point(this.x - p.x, this.y - p.y);
}
}
因此,如果您通过translate(offsetX,offsetY)scale(scale)
给出了转换,并且在(mouseX,mouseY)
处发生了一个滚动事件,导致了一个新的缩放newScale
,您可以通过以下方式计算新的转换:
offsetX = (offsetX - mouseX) * newScale/scale + mouseX
offsetY = (offsetY - mouseY) * newScale/scale + mouseY