调整大小和滚动问题(JS/HTML) [英] Resizing and scrolling issue (JS/HTML)

查看:36
本文介绍了调整大小和滚动问题(JS/HTML)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有两个容器:第一个是小视口,第二个是大工作区.因此,用户滚动视口以在工作空间内移动.我想通过CSS属性 transform 实现放大/缩小功能,但是在此过程中,我遇到了一个困难,无法为其找到精确的解决方案.

There are two containers: the first is a small viewport and the second is huge workspace. So, user scroll the viewport to move within the workspace. I want to implement a zoom in/out feature via CSS property tranform, but during the process I faced one difficulty and could not find a precise solution for it.

问题是:当用户放大/缩小时,工作区中的元素会移动.发生这种情况实际上是因为调整了工作空间的大小,而不是它们的大小.但是,如果我在工作区中调整每个元素的大小,它们之间的距离(以 top/left CSS值表示)将被更改,这不是首选.

The issue is: when user zooms in/out, elements at the workspace are shifted. This happens actually because the workspace is resized, not they. But if I resize each element at the workspace, the distances between them (in terms of top/left CSS values) will be changed, what is not preferred.

我看到以下解决方案:在调整大小后更改滚动值,但是我不知道要使用什么比例或数字.是否有解决此问题的公式或其他解决方案?

I see the following solution: change scrolls values after resizing, but I do not know what ratios or numbers to use. Is there any formulae or another solution to overcome such a problem?

要调整大小,请使用 Alt + MouseWheel

let workspace = document.getElementsByClassName('workspace')[0];
workspace.onwheel = resize;

let current_scale = 1;

function resize(E) {
  E = E || window.event
  if (E.altKey) {
    E.preventDefault();
    let new_scale = Math.max(0.1, current_scale - E.deltaY / 360);
    workspace.style.setProperty('transform', 'scale(' + new_scale + ')');
    current_scale = new_scale;
  }
}

.viewport {
  width: 80vw;
  height: 80vh;
  box-sizing: border-box;
  overflow: scroll;
 
  transform: scale(1);
}

.workspace {
  position: relative;
  width: 1000px;
  height: 1000px;
  overflow: hidden;
}

.element {
  position: absolute;
  width: 10px;
  height: 10px;
}

<div class="viewport">
  <div class="workspace">
    <button class="element" style="top: 100px; left: 150px"></button>
    <button class="element" style="top 80px; left: 100px"></button>
    <button class="element" style="top: 230px; left: 130px"></button>
    <button class="element" style="top: 100px; left: 250px"></button>
  </div>
</div>

UPD :我附上了原始项目中的一些照片以供澄清:

UPD: I attached some photos from the original project for clarification:

所以,这就是带有 scale(1)的工作区的外观

So, that's a look of the workspace with scale(1)

然后我调整其大小并得到以下结果:

Then I resize it and get the following result:

但是理想的结果如下所示:

But desirable result looks like this:

UPD2 我插入了< svg> 元素以显示如何绘制线条以及为什么在我看来对于调整每个按钮的大小都不可行

UPD2 I inserted <svg> element to show how lines are drawn and why resizing each button seems to me a not viable solution in my case

 let workspace = document.getElementsByClassName('workspace')[0];
    workspace.onwheel = resize;
    let current_scale = 1;
    function resize(E) {
        E = E || window.event;
        if (E.altKey) {
            E.preventDefault();
            let new_scale = Math.max(0.1, current_scale - E.deltaY / 360);
            var btns = workspace.getElementsByClassName('element');
            for(var i = 0; i <btns.length; i++) {
                btns[i].style.setProperty('transform', 'scale(' + new_scale + ')');
            }
            current_scale = new_scale;
        }
    }

.viewport {
            width: 80vw;
            height: 80vh;
            box-sizing: border-box;
            overflow: scroll;

            transform: scale(1);
            transform-origin: 0 0;
        }

        .workspace {
            position: relative;
            width: 1000px;
            height: 1000px;
            overflow: hidden;
        }

        .element {
            position: absolute;
            width: 10px;
            height: 10px;
        }
        .line-drawer
        {
            position:absolute;
            height:1000px;
            width:1000px;
        }

<div class="viewport">
    <div class="workspace">
        <svg class="line-drawer">
            <line x1="100px" x2="130px" y1="80px" y2="230px" style='stroke-width: 4px; stroke: black'></line>
        </svg>
        <button class="element" style="top: 100px; left: 150px"></button>
        <button class="element" style="top: 80px; left: 100px"></button>
        <button class="element" style="top: 230px; left: 130px"></button>
        <button class="element" style="top: 100px; left: 250px"></button>
    </div>
</div>

推荐答案

按比例缩放单个元素会将它们保持在该位置

Scaling the individual elements like this will keep them in there position

let workspace = document.getElementsByClassName('workspace')[0];
workspace.onwheel = resize;

let current_scale = 1;

function resize(E) {
  E = E || window.event
  if (E.altKey) {
    E.preventDefault();
    let new_scale = Math.max(0.1, current_scale - E.deltaY / 360);
    var btns = workspace.getElementsByClassName('element');
    for(var i = 0; i <btns.length; i++) { 
        btns[i].style.setProperty('transform', 'scale(' + new_scale + ')');
    }
    current_scale = new_scale;
  }
}

.viewport {
  width: 80vw;
  height: 80vh;
  box-sizing: border-box;
  overflow: scroll;
 
  transform: scale(1);
}

.workspace {
  position: relative;
  width: 1000px;
  height: 1000px;
  overflow: hidden;
}

.element {
  position: absolute;
  width: 10px;
  height: 10px;
}

<div class="viewport">
  <div class="workspace">
    <button class="element" style="top: 100px; left: 150px"></button>
    <button class="element" style="top 80px; left: 100px"></button>
    <button class="element" style="top: 230px; left: 130px"></button>
    <button class="element" style="top: 100px; left: 250px"></button>
  </div>
</div>

这篇关于调整大小和滚动问题(JS/HTML)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆