Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript SVG放大鼠标-数学模型_Javascript_Css_Svg - Fatal编程技术网

Javascript SVG放大鼠标-数学模型

Javascript SVG放大鼠标-数学模型,javascript,css,svg,Javascript,Css,Svg,在您思考“为什么这个家伙在这个问题上寻求帮助,这肯定已经实现了1000x”之前,虽然您基本上是正确的,但我已经尝试用几个开源lib来解决这个问题 我试图从头开始实现一个基于SVG的“放大鼠标滚轮,聚焦鼠标” 我知道有很多库可以实现这一点,d3和svg平移缩放就是其中之一。不幸的是,我使用这些lib的实现没有达到我的预期。我希望我能从社区那里得到一些帮助,为这种类型的UI特性建立基本的数学模型 基本上,所需的行为类似于谷歌地图,用户将鼠标悬停在某个位置上,滚动鼠标滚轮(向内),地图图像的比例增加,

在您思考“为什么这个家伙在这个问题上寻求帮助,这肯定已经实现了1000x”之前,虽然您基本上是正确的,但我已经尝试用几个开源lib来解决这个问题

我试图从头开始实现一个基于SVG的“放大鼠标滚轮,聚焦鼠标”

我知道有很多库可以实现这一点,d3和svg平移缩放就是其中之一。不幸的是,我使用这些lib的实现没有达到我的预期。我希望我能从社区那里得到一些帮助,为这种类型的UI特性建立基本的数学模型

基本上,所需的行为类似于谷歌地图,用户将鼠标悬停在某个位置上,滚动鼠标滚轮(向内),地图图像的比例增加,而悬停的位置成为视口的水平和垂直中心

当然,我可以访问视口的宽度/高度和鼠标的x/y

在本例中,我将仅关注x轴,视口宽度为900单位,正方形宽度为100单位,其x偏移为400单位,比例为1:1

<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