【问题标题】:Calculation of a mouse position after multiple scales on different coordinates of image在图像的不同坐标上多次缩放后计算鼠标位置
【发布时间】:2020-06-13 16:19:18
【问题描述】:

我正在编写一个图像查看器 JS 组件,我目前停留在放大的计算上。我使用 css 变换计算了在一个点(而不仅仅是中心)上的放大或缩小。我没有使用变换原点,因为会有多个放大或缩小点,并且位置必须反映这一点。然而,这正是我卡住的地方。当鼠标实际从初始位置移动时,我使用的算法在尝试放大(或缩小)后无法正确计算偏移量,并且我一生都无法弄清楚等式中缺少什么。

目标是每当鼠标移动到另一个位置时,整个图像应该以该位置为原点进行缩放,这意味着图像应该缩放但鼠标所在的点应该保持在原位。 作为参考,请查看this JS 组件。加载图像,放大某处,将鼠标移动到另一个位置并再次放大。

这是在我的代码中演示问题的笔:https://codepen.io/Emberfire/pen/jOWrVKB

如果有人知道我错过了什么,我真的很感激 :)

这是 HTML

<div class="container">
    <div class="wrapper">
        <div class="image-wrapper">
            <img class="viewer-img" src="https://cdn.pixabay.com/photo/2020/06/08/17/54/rain-5275506_960_720.jpg" draggable="false" />
        </div>
    </div>
</div>

这是我用于组件的 css:

* {
    box-sizing: border-box;
}

html, body {
    width: 100%;
    height: 100%;
    margin: 0;
}

.container {
    width: 100%;
    height: 100%;
}

.wrapper {
    width: 100%;
    height: 100%;
    overflow: hidden;
    transition: all .1s;
    position: relative;
}

.image-wrapper {
    position: absolute;
}

.wrapper img {
    position: absolute;
    transform-origin: top left;
}

这是计算位置和比例的脚本:

let wrapper = document.querySelector(".wrapper");
let image = wrapper.querySelector(".image-wrapper");
let scale = 1;
image.querySelector("img").addEventListener("wheel", (e) => {
    if (e.deltaY < 0) {
        scale = Number((scale * 1.2).toFixed(2));

        let scaledX = e.offsetX * scale;
        let scaledY = e.offsetY * scale;

        imageOffsetX = e.offsetX - scaledX;
        imageOffsetY = e.offsetY - scaledY;

        e.target.style.transform = `scale3d(${scale}, ${scale}, ${scale})`;
        image.style.transform = `translate(${imageOffsetX.toFixed(2)}px, ${imageOffsetY.toFixed(2)}px)`;
    } else {
        scale = Number((scale / 1.2).toFixed(2));

        let scaledX = e.offsetX * scale;
        let scaledY = e.offsetY * scale;

        imageOffsetX = e.offsetX - scaledX;
        imageOffsetY = e.offsetY - scaledY;

        e.target.style.transform = `scale3d(${scale}, ${scale}, ${scale})`;
        image.style.transform = `translate(${imageOffsetX}px, ${imageOffsetY}px)`;
    }
});

【问题讨论】:

  • 有趣的问题。已经解决了吗?如果你还没有回答,我今天会尝试解决它
  • @AksJacoves 我没有,不。我想通了页面的顺利拖动,但缩放仍然不完整。谢谢你的努力:)

标签: javascript html css


【解决方案1】:

想了想,我明白了算法失败的地方。您的计算集中在图像的 offsetx 和 offsety 的信息上,问题是您正在处理 scale 和 scale 的数据,如 offsetx 和 offsety 没有更新,他们看到了常量。所以我停止使用“宽度”方法使用比例放大图像。还需要创建两个变量“accx”和“accy”来接收翻译的累积值

let wrapper = document.querySelector(".wrapper");
let image = wrapper.querySelector(".image-wrapper");
let img = document.querySelector('img')
let scale = 1;
let accx = 0, accy = 0
image.querySelector("img").addEventListener("wheel", (e) => {
  if (e.deltaY < 0) {
    scale = Number((scale * 1.2));
    accx += Number(e.offsetX * scale/1.2 - e.offsetX * scale)
    accy += Number(e.offsetY * scale/1.2 - e.offsetY * scale)

  } else {
    scale = Number((scale / 1.2));
    accx += Number(e.offsetX * scale * 1.2 - e.offsetX * scale)
    accy += Number(e.offsetY * scale * 1.2 - e.offsetY * scale)
  }
  e.target.style.transform = `scale3D(${scale}, ${scale}, ${scale})`
  image.style.transform = `translate(${accx}px, ${accy}px)`;
});
* {
  box-sizing: border-box;
}

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
}

.container {
  width: 100%;
  height: 100%;
  position: relative;
}

.wrapper {
  width: 100%;
  height: 100%;
  overflow: hidden;
  transition: all 0.1s;
  position: relative;
}

.image-wrapper {
  position: absolute;
}

.wrapper img {
  position: absolute;
  transform-origin: top left;
}

.point {
  width: 4px;
  height: 4px;
  background: #f00;
  position: absolute;
}
<div class="container">
  <div class="wrapper">
    <div class="image-wrapper">
      <img class="viewer-img" src="https://cdn.pixabay.com/photo/2020/06/08/17/54/rain-5275506_960_720.jpg" draggable="false" />
    </div>
  </div>
</div>

在这里预览效果:JsFiddle

【讨论】:

  • 嘿,感谢您回来并提供解决方案 :) 我尝试了您的版本,它成功了!但是,我最初只使用变换是为了避免不必要的浏览器重排(因为图像位于绝对容器中)并尽可能利用 GPU 渲染。将 offsetX 乘以当前比例是否可以达到相同的结果?谢谢你的时间:)
  • 我没有考虑计算成本方面,你是对的。我将使用 scale3D 编辑我的答案,计算非常简单
  • 这很完美!现在深入研究并完全理解我做错了什么......无论如何,非常感谢你帮助我
猜你喜欢
  • 2018-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-18
  • 2020-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多