在javascript中缩放到不带画布的光标

在javascript中缩放到不带画布的光标,javascript,css,zooming,Javascript,Css,Zooming,我有一个,通过调整transform:scale(),鼠标滚轮滚动时可以缩放。我希望缩放像在谷歌地图中一样,缩放到鼠标光标所在的位置,而不是图像的中心。我不想使用画布,只是为了学习经验(这也是为什么我发现的其他问题没有真正帮助) 我建立了一个模型来演示这个问题。我的思考过程如下:放大10%时,图像从图像中心向各个方向扩展10%。这意味着,例如,左右边缘将在每个方向上移动原始宽度的5%。因此,我试图这样解决问题: 计算鼠标相对于图像中心的偏移量 将鼠标偏移量乘以缩放因子并除以2,计算新图像偏移量(

我有一个
,通过调整
transform:scale()
,鼠标滚轮滚动时可以缩放。我希望缩放像在谷歌地图中一样,缩放到鼠标光标所在的位置,而不是图像的中心。我不想使用画布,只是为了学习经验(这也是为什么我发现的其他问题没有真正帮助)

我建立了一个模型来演示这个问题。我的思考过程如下:放大10%时,图像从图像中心向各个方向扩展10%。这意味着,例如,左右边缘将在每个方向上移动原始宽度的5%。因此,我试图这样解决问题:

  • 计算鼠标相对于图像中心的偏移量
  • 将鼠标偏移量乘以缩放因子并除以2,计算新图像偏移量(顶部和左侧)
  • 应用偏移量,看着它用一百万个燃烧的太阳的能量把我的脸炸开

  • 似乎我就是找不到适合的公式或算法。

    您可以使用
    变换原点:

    • 变换原点:0%0%
      位于左上角的点
    • 变换原点:100%100%
      位于右下角的点
    下面是我举的一个例子:

    javaScript:

    var currentzoom = 1;
    
    function zoom(delta, e) {
       var img = document.getElementById("test");
       var width = img.offsetWidth; //calculating the size of the img (in px)
       var height = img.offsetHeight;
       var x = event.offsetX; //calculating the position of the mouse pointer on the picture (in px)
       var y = event.offsetY; 
       var xpercent = x*100/width; //calculating the position of the mouse pointer on the picture (in %)
       var ypercent = y*100/height;
       img.style.transform = "scale("+currentzoom+")"; //scaling the picture
       img.style.transformOrigin = xpercent + "% "+ ypercent +"%"; //transform-origin
       currentzoom += delta;
    }
    

    最终我自己找到了答案,尽管只是通过查看现有的解决方案。以下是仅包含基本要素的示例

    其思想是首先设置
    变换原点:0
    。这可以确保在缩放时,图像向下和向右扩展,而不是将宽度的增加分布到所有四个边上。请注意,它不会重新定位图像,它只是

    此外,此JSFIDLE假设图像的上边缘和左边缘与容器元素的上边缘和左边缘对齐。如果在进行缩放之前应重新定位图像,则应通过
    transform:translate()
    执行此操作,并且需要相应地更新
    translateX
    translateY

    逻辑的核心是:

      // Track the percentage change between the old
      // and the new scale of the image
      const ratio = 1 - nextScale / currentScale
    
      // get the current mouse offset
      const {
        clientX,
        clientY
      } = event
    
      // The += here is extremely important!
      // The new 2D translation values are derived from the difference
      // between mouse cursor position and current (!) 2D translation.
      // So where is the mouse cursor relative to the translated image
      // This difference is then adjusted by the % change of the scaling
      translateX += (clientX - translateX) * ratio
      translateY += (clientY - translateY) * ratio
    
      /*
      This would work for the first mousewheel scroll. But afterwards, the 
      image will not be translated enough to offset the zooming because 
      we're not taking into account the existing translation
      translateX += (clientX - translateX) * ratio
      translateY += (clientY - translateY) * ratio
      */
    
    因此,要总结所需的步骤:

  • 计算下一个刻度
  • 计算相对于转换图像的当前鼠标偏移
  • 根据缩放比例的变化调整鼠标偏移量,例如,
    const percentChange=1-nextScale/currentScale
  • 将调整后的鼠标偏移量添加到
    translate()
  • 应用变换(缩放和平移)

  • 这仅适用于初始缩放。如果您放大一个点,然后将鼠标指向其他点并放大,它将断开。感觉有点像我遇到的问题。