您的问题主要围绕以下几行
const x = Math.round(divMain.scrollLeft * scaleChange)
const y = Math.round(divMain.scrollTop * scaleChange)
带比例滚动的方式如下所示
- 计算未缩放的
x, y
缩放发生的坐标
- 计算新的缩放比例
x, y
协调我将其与新比例相乘
- 现在您希望这个新坐标保留在现有坐标所在的位置。所以基本上如果你减去
offset x,y
从新的scaled x,y
,您可以向左和顶部滚动。
更新后的代码如下
for (const divMain of document.getElementsByClassName('main')) {
// drag the section
for (const divSection of divMain.getElementsByClassName('section')) {
// when mouse is pressed store the current mouse x,y
let previousX, previousY
divSection.addEventListener('mousedown', (event) => {
previousX = event.pageX
previousY = event.pageY
})
// when mouse is moved, scrollBy() the mouse movement x,y
divSection.addEventListener('mousemove', (event) => {
// only do this when the primary mouse button is pressed (event.buttons = 1)
if (event.buttons) {
let dragX = 0
let dragY = 0
// skip the drag when the x position was not changed
if (event.pageX - previousX !== 0) {
dragX = previousX - event.pageX
previousX = event.pageX
}
// skip the drag when the y position was not changed
if (event.pageY - previousY !== 0) {
dragY = previousY - event.pageY
previousY = event.pageY
}
// scrollBy x and y
if (dragX !== 0 || dragY !== 0) {
divMain.scrollBy(dragX, dragY)
}
}
})
}
// zoom in/out on the section
let scale = 1
const factor = 0.05
const max_scale =4
divMain.addEventListener('wheel', (e) => {
// preventDefault to stop the onselectionstart event logic
for (const divSection of divMain.getElementsByClassName('section')) {
e.preventDefault();
var delta = e.delta || e.wheelDelta;
if (delta === undefined) {
//we are on firefox
delta = e.originalEvent.detail;
}
delta = Math.max(-1,Math.min(1,delta)) // cap the delta to [-1,1] for cross browser consistency
offset = {x: divMain.scrollLeft, y: divMain.scrollTop};
image_loc = {
x: e.pageX + offset.x,
y: e.pageY + offset.y
}
zoom_point = {x:image_loc.x/scale, y: image_loc.y/scale}
// apply zoom
scale += delta*factor * scale
scale = Math.max(1,Math.min(max_scale,scale))
zoom_point_new = {x:zoom_point.x * scale, y: zoom_point.y * scale}
newScroll = {
x: zoom_point_new.x - e.pageX,
y: zoom_point_new.y - e.pageY
}
divSection.style.transform = `scale(${scale}, ${scale})`
divMain.scrollTop = newScroll.y
divMain.scrollLeft = newScroll.x
}
})
}
更新的小提琴是
https://jsfiddle.net/uy390v8t/1/ https://jsfiddle.net/uy390v8t/1/