在没有鼠标和键盘按钮的情况下放大时 Panzoom 不一致 [英] Panzoom inconsistent when zooming in without a mouse and keyboard buttons

查看:40
本文介绍了在没有鼠标和键盘按钮的情况下放大时 Panzoom 不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已尝试在此 github 帖子

中发布的解决方案

重现步骤:

  1. 点击放大按钮两次.
  2. 当缩放为 150% 时;点击缩小.

图像放大但实际上应该缩小

const element = document.querySelector('#scene');const zoomLevels = [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.5, 3];让 currentZoomLevel = zoomLevels[4];const text = document.querySelector('#text');让 panZoomController = panzoom(元素,{前轮:功能(e){//允许滚轮缩放禁用返回真;}});const setText = (输入) =>{text.innerText = 输入;}const zoom = () =>{const isSmooth = false;const scale = currentZoomLevel;如果(规模){const 变换 = panZoomController.getTransform();const deltaX = transform.x;const deltaY = transform.y;const offsetX = 比例 + deltaX;const offsetY = 比例 + deltaY;如果(是平滑的){panZoomController.smoothZoom(0, 0, scale);} 别的 {panZoomController.zoomTo(offsetX, offsetY, scale);}}};const zoomIn = () =>{const idx = zoomLevels.indexOf(currentZoomLevel);//如果下一个元素存在if (typeof zoomLevels[idx + 1] !== 'undefined') {currentZoomLevel = zoomLevels[idx + 1];}如果(当前缩放级别 === 1){panZoomController.moveTo(0, 0);panZoomController.zoomAbs(0, 0, 1);} 别的 {飞涨();}setText(currentZoomLevel * 100 + '%');};const zoomOut = () =>{const idx = zoomLevels.indexOf(currentZoomLevel);//如果前一个元素存在if (typeof zoomLevels[idx - 1] !== 'undefined') {currentZoomLevel = zoomLevels[idx - 1];}如果(当前缩放级别 === 1){panZoomController.moveTo(0, 0);panZoomController.zoomAbs(0, 0, 1);} 别的 {飞涨();}setText(currentZoomLevel * 100 + '%');};

div {溢出:隐藏;边框:3px纯红色}

<script src="https://unpkg.com/panzoom@8.1.0/dist/panzoom.min.js"></脚本><身体><div><img id="scene" src="https://www.probytes.net/wp-content/uploads/2018/01/5-1.png">

<br/><button onclick="zoomOut()">-</button><span id="text">100%</span><button onclick="zoomIn()">+</button>

解决方案

您在此处将相对比例误认为是绝对比例.zoomAbs() 使用绝对缩放级别,而 zoom() 函数使用 zoomTo() 获取相对缩放级别.

因此,描述您的整个过程:

 - 初始.规模:1- 放大.比例:1 * 1.25 = 1.25- 放大.比例:1.25 * 1.5 = 1.875- 缩小.比例:1.875 * 1.25 = 2.344- 缩小.比例:硬重置为 1

注意:如果您多次缩小,然后尝试放大,您也可以看到相反的情况发生.

这可以通过使用绝对缩放方法zoomAbs()(更简单)或使用当前和所需缩放计算相对缩放来解决.

要做到这一点,只需替换这一行

panZoomController.zoomTo(offsetX, offsetY, scale);

panZoomController.zoomAbs(offsetX, offsetY, scale);

固定片段:

const element = document.querySelector('#scene');const zoomLevels = [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.5, 3];让 currentZoomLevel = zoomLevels[4];const text = document.querySelector('#text');让 panZoomController = panzoom(元素,{前轮:功能(e){//允许滚轮缩放禁用返回真;}});const setText = (输入) =>{text.innerText = 输入;}const zoom = () =>{const isSmooth = false;const scale = currentZoomLevel;如果(规模){const transform = panZoomController.getTransform();const deltaX = transform.x;const deltaY = transform.y;const offsetX = 比例 + deltaX;const offsetY = 比例 + deltaY;如果(是平滑的){panZoomController.smoothZoom(0, 0, scale);} 别的 {panZoomController.zoomAbs(offsetX, offsetY, scale);}}};const zoomIn = () =>{const idx = zoomLevels.indexOf(currentZoomLevel);//如果下一个元素存在if (typeof zoomLevels[idx + 1] !== 'undefined') {currentZoomLevel = zoomLevels[idx + 1];}如果(当前缩放级别 === 1){panZoomController.moveTo(0, 0);panZoomController.zoomAbs(0, 0, 1);} 别的 {飞涨();}setText(currentZoomLevel * 100 + '%');};const zoomOut = () =>{const idx = zoomLevels.indexOf(currentZoomLevel);//如果前一个元素存在if (typeof zoomLevels[idx - 1] !== 'undefined') {currentZoomLevel = zoomLevels[idx - 1];}如果(当前缩放级别 === 1){panZoomController.moveTo(0, 0);panZoomController.zoomAbs(0, 0, 1);} 别的 {飞涨();}setText(currentZoomLevel * 100 + '%');};

div {溢出:隐藏;边框:3px纯红色}

<script src="https://unpkg.com/panzoom@8.1.0/dist/panzoom.min.js"></脚本><身体><div><img id="scene" src="https://www.probytes.net/wp-content/uploads/2018/01/5-1.png">

<br/><button onclick="zoomOut()">-</button><span id="text">100%</span><button onclick="zoomIn()">+</button>

I have tried the solution posted in this github post

Steps to reproduce:

  1. Click on Zoom in Button twice.
  2. When Zoom is 150%; Click zoom out.

The image zooms in but should actually zoom out

const element = document.querySelector('#scene');

const zoomLevels = [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.5, 3];
let currentZoomLevel = zoomLevels[4];
const text = document.querySelector('#text');

let panZoomController = panzoom(element, {
  beforeWheel: function(e) {
    // allow wheel-zoom Disabled
    return true;
  }
});

const setText = (input) => {
  text.innerText = input;
}

const zoom = () => {
  const isSmooth = false;
  const scale = currentZoomLevel;
  if (scale) {
    const transform = panZoomController.getTransform();
    const deltaX = transform.x;
    const deltaY = transform.y;
    const offsetX = scale + deltaX;
    const offsetY = scale + deltaY;

    if (isSmooth) {
      panZoomController.smoothZoom(0, 0, scale);
    } else {
      panZoomController.zoomTo(offsetX, offsetY, scale);
    }
  }
};


const zoomIn = () => {
  const idx = zoomLevels.indexOf(currentZoomLevel);

  // If next element exists
  if (typeof zoomLevels[idx + 1] !== 'undefined') {
    currentZoomLevel = zoomLevels[idx + 1];
  }

  if (currentZoomLevel === 1) {
    panZoomController.moveTo(0, 0);
    panZoomController.zoomAbs(0, 0, 1);
  } else {
    zoom();
  }
  setText(currentZoomLevel * 100 + '%');

};

const zoomOut = () => {
  const idx = zoomLevels.indexOf(currentZoomLevel);

  //if previous element exists
  if (typeof zoomLevels[idx - 1] !== 'undefined') {
    currentZoomLevel = zoomLevels[idx - 1];
  }


  if (currentZoomLevel === 1) {
    panZoomController.moveTo(0, 0);
    panZoomController.zoomAbs(0, 0, 1);
  } else {
    zoom();
  }

  setText(currentZoomLevel * 100 + '%');
};

div {
  overflow: hidden;
  border: 3px solid red
}

<script src="https://unpkg.com/panzoom@8.1.0/dist/panzoom.min.js"></script>

<body>
  <div>
    <img id="scene" src="https://www.probytes.net/wp-content/uploads/2018/01/5-1.png">
  </div>

  <br/>
  <button onclick="zoomOut()">-</button>
  <span id="text">100%</span>
  <button onclick="zoomIn()">+</button>
</body>

解决方案

You have mistaken a relative scale for an absolute one here. While zoomAbs() is using an absolute zoom level, the zoom() function is using zoomTo() which takes in a relative zoom level.

Therefore, describing your entire process:

 - Initial.  Scale: 1
 - Zoom in.  Scale: 1 * 1.25 = 1.25
 - Zoom in.  Scale: 1.25 * 1.5 = 1.875
 - Zoom out. Scale: 1.875 * 1.25 = 2.344
 - Zoom out. Scale: Hard reset to 1

Note: You can also see this happening in reverse if you zoom out more than once, then try to zoom in.

This can be remedied by either using the absolute scale method zoomAbs() (much simpler) or by calculating the relative zoom using current and required scales.

To do this simply replace this line

panZoomController.zoomTo(offsetX, offsetY, scale);

with

panZoomController.zoomAbs(offsetX, offsetY, scale);

Fixed snippet:

const element = document.querySelector('#scene');

const zoomLevels = [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.5, 3];
let currentZoomLevel = zoomLevels[4];
const text = document.querySelector('#text');

let panZoomController = panzoom(element, {
  beforeWheel: function(e) {
    // allow wheel-zoom Disabled
    return true;
  }
});

const setText = (input) => {
  text.innerText = input;
}

const zoom = () => {
  const isSmooth = false;
  const scale = currentZoomLevel;
  if (scale) {
    const transform = panZoomController.getTransform();
    const deltaX = transform.x;
    const deltaY = transform.y;
    const offsetX = scale + deltaX;
    const offsetY = scale + deltaY;

    if (isSmooth) {
      panZoomController.smoothZoom(0, 0, scale);
    } else {
      panZoomController.zoomAbs(offsetX, offsetY, scale);
    }
  }
};


const zoomIn = () => {
  const idx = zoomLevels.indexOf(currentZoomLevel);

  // If next element exists
  if (typeof zoomLevels[idx + 1] !== 'undefined') {
    currentZoomLevel = zoomLevels[idx + 1];
  }

  if (currentZoomLevel === 1) {
    panZoomController.moveTo(0, 0);
    panZoomController.zoomAbs(0, 0, 1);
  } else {
    zoom();
  }
  setText(currentZoomLevel * 100 + '%');

};

const zoomOut = () => {
  const idx = zoomLevels.indexOf(currentZoomLevel);

  //if previous element exists
  if (typeof zoomLevels[idx - 1] !== 'undefined') {
    currentZoomLevel = zoomLevels[idx - 1];
  }


  if (currentZoomLevel === 1) {
    panZoomController.moveTo(0, 0);
    panZoomController.zoomAbs(0, 0, 1);
  } else {
    zoom();
  }

  setText(currentZoomLevel * 100 + '%');
};

div {
  overflow: hidden;
  border: 3px solid red
}

<script src="https://unpkg.com/panzoom@8.1.0/dist/panzoom.min.js"></script>

<body>
  <div>
    <img id="scene" src="https://www.probytes.net/wp-content/uploads/2018/01/5-1.png">
  </div>

  <br/>
  <button onclick="zoomOut()">-</button>
  <span id="text">100%</span>
  <button onclick="zoomIn()">+</button>
</body>

这篇关于在没有鼠标和键盘按钮的情况下放大时 Panzoom 不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆