我有一个<img>
通过调整鼠标滚轮滚动来缩放transform: scale()
。我希望缩放像 Google 地图一样,您可以缩放到鼠标光标所在的位置,而不是图像的中心。不过,我不想使用画布,只是为了学习体验(这也是我发现的其他问题并没有真正帮助的原因)。
我设置了一个JSFiddle https://jsfiddle.net/un17phdg/3/来演示问题。我的思考过程如下:当放大10%时,图像从图像中心向各个方向扩展10%。这意味着,例如,左边缘和右边缘将在每个方向上移动原始宽度的 5%。因此我尝试像这样解决这个问题:
- 计算鼠标距图像中心的偏移量
- 通过将鼠标偏移乘以缩放系数并除以二来计算新图像偏移(顶部和左侧)
- 应用胶印,看着它用一百万个燃烧的太阳的力量炸毁我的脸
看来我就是找不到合适的公式或算法。
最终我自己解决了这个问题,尽管只是通过查看现有的解决方案。这里是JSFiddle https://jsfiddle.net/rfpe0mhq/只包含必需品。
想法是首先设定transform-origin: 0 0
。这可以确保在缩放时图像向下和向右扩展,而不是在所有四个边上分布宽度的增加。请注意,它不会重新定位图像,它只是更改所有转换的原点 https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin.
此外,此 JSFiddle 假定图像的上边距和左边距与容器元素的上边距和左边距对齐。如果在缩放之前应重新定位图像,则应通过transform: translate()
和translateX
and 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 wheel 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()
- 应用变换(缩放和平移)
链接的 JSFiddle 还包括 Lodash 和transition: transform 330ms ease-in-out;
使滚动更加平滑,并且不会过多影响浏览器性能。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)