Javascript 平移和滚轮缩放图像

问题描述 投票:0回答:1

我有以下用于平移图像的代码。平移效果很好,但滚轮缩放效果不佳。当我开始缩放图像上方的任何位置时,我希望它从光标点向外缩放。当前图像从鼠标移动。

var mouseX,
  mouseY,
  mouseTX,
  mouseTY,
  panning = false,
  panEventAdded,
  ts = {
    scale: 1,
    translate: {
      x: 0,
      y: 0
    }
  }


var boxChildWrap = document.querySelector(".aplbox-child");

addPanEvents()

function addPanEvents() {

  panEventAdded = true;

  boxChildWrap.onpointerdown = pointerdownHandler;

  boxChildWrap.onpointerup = pointerupHandler;
  boxChildWrap.onpointercancel = pointerupHandler;
  boxChildWrap.onpointerout = pointerupHandler;
  boxChildWrap.onpointerleave = pointerupHandler;
  document.onpointerup = pointerupHandler;

}

function pointerdownHandler(e) {
  e.preventDefault();


  panning = true;

  mouseX = e.clientX;
  mouseY = e.clientY;
  mouseTX = ts.translate.x;
  mouseTY = ts.translate.y;

  boxChildWrap.onpointermove = pointermoveHandler
};

function pointermoveHandler(e) {
  e.preventDefault();

  let rec = boxChildWrap.getBoundingClientRect();

  const x = e.clientX;
  const y = e.clientY;

  if (!panning) {
    return;
  }

  ts.translate.x = mouseTX + (x - mouseX);
  ts.translate.y = mouseTY + (y - mouseY);

  setTransform();

};

function pointerupHandler(e) {
  panning = false;
  boxChildWrap.onpointermove = null
}

function setTransform() {
  const transform = 'translate(' + ts.translate.x + 'px,' + ts.translate.y + 'px) scale(' + ts.scale + ') translate3d(0,0,0)';
  boxChildWrap.style.transform = transform;
  boxChildWrap.style.transition = '';
}

boxChildWrap.addEventListener("wheel", function(e) {

  var xs = (e.clientX - ts.translate.x) / ts.scale,
    ys = (e.clientY - ts.translate.y) / ts.scale,
    delta = (e.wheelDelta ? e.wheelDelta : -e.deltaY);
  (delta > 0) ? (ts.scale *= 1.2) : (ts.scale /= 1.2);

  ts.translate.x = e.clientX - xs * ts.scale;
  ts.translate.y = e.clientY - ys * ts.scale;

  setTransform();

})
.aplbox-child {
  max-height: 100% !important;
  max-width: 100% !important;
  position: relative;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  transform: scale(1);
  transition: transform;
  touch-action: none;
}

.aplbox-child img {
  user-select: none;
  display: block;
  max-height: 100%;
  max-width: 100%;
}
<div class="aplbox-child aplbox-image"><img src="https://picsum.photos/1280/720"></div>

javascript html css zooming mousewheel
1个回答
0
投票

如果您希望代码缩放图片,则需要使用

scale
内的
ts
属性。将图片置于光标中心需要平移图片,但这也意味着新坐标在事件和下一个事件之间发生了变化。您需要准确定义您想要什么。例如,坐标会被冻结直到用户移动鼠标吗?

var mouseX,
  mouseY,
  mouseTX,
  mouseTY,
  panning = false,
  panEventAdded,
  ts = {
    scale: 1,
    translate: {
      x: 0,
      y: 0
    }
  }


var boxChildWrap = document.querySelector(".aplbox-child");

addPanEvents()

function addPanEvents() {

  panEventAdded = true;

  boxChildWrap.onpointerdown = pointerdownHandler;

  boxChildWrap.onpointerup = pointerupHandler;
  boxChildWrap.onpointercancel = pointerupHandler;
  boxChildWrap.onpointerout = pointerupHandler;
  boxChildWrap.onpointerleave = pointerupHandler;
  document.onpointerup = pointerupHandler;

}

function pointerdownHandler(e) {
  e.preventDefault();


  panning = true;

  mouseX = e.clientX;
  mouseY = e.clientY;
  mouseTX = ts.translate.x;
  mouseTY = ts.translate.y;

  boxChildWrap.onpointermove = pointermoveHandler
};

function pointermoveHandler(e) {
  e.preventDefault();

  let rec = boxChildWrap.getBoundingClientRect();

  const x = e.clientX;
  const y = e.clientY;

  if (!panning) {
    return;
  }

  ts.translate.x = mouseTX + (x - mouseX);
  ts.translate.y = mouseTY + (y - mouseY);

  setTransform();

};

function pointerupHandler(e) {
  panning = false;
  boxChildWrap.onpointermove = null
}

function setTransform() {
  const transform = 'translate(' + ts.translate.x + 'px,' + ts.translate.y + 'px) scale(' + ts.scale + ') translate3d(0,0,0)';
  boxChildWrap.style.transform = transform;
  boxChildWrap.style.transition = '';
}

boxChildWrap.addEventListener("wheel", function(e) {

  var xs = e.clientX;
    ys = e.clientY;
    delta = (e.wheelDelta ? e.wheelDelta : -e.deltaY);
  (delta > 0) ? (ts.scale *= 1.2) : (ts.scale /= 1.2);

  ts.scale = ts.scale + delta / 100;

  setTransform();

})
.aplbox-child {
  max-height: 100% !important;
  max-width: 100% !important;
  position: relative;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  transform: scale(1);
  transition: transform;
  touch-action: none;
}

.aplbox-child img {
  user-select: none;
  display: block;
  max-height: 100%;
  max-width: 100%;
}
<div class="aplbox-child aplbox-image"><img src="https://picsum.photos/1280/720"></div>

© www.soinside.com 2019 - 2024. All rights reserved.