首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >向相反方向移动mousemove上的元素

向相反方向移动mousemove上的元素
EN

Stack Overflow用户
提问于 2022-06-30 09:31:18
回答 1查看 91关注 0票数 -1

while语句在"onmousemove"事件中似乎不起作用

我正在尝试制作一个水平滚动页面,该页面用鼠标位置滚动。我设法让它用

代码语言:javascript
复制
<script>
        const width = window.innerWidth;
        const height = window.innerHeight;
        const windowCenterX = width / 2;
        const windowCenterY = height / 2;
        document.onmousemove = function(e){
            var x = e.clientX; 
            var y = e.clientY;
            const transformedX = x - windowCenterX;
            document.getElementById("mouse-value").innerHTML = transformedX;
            document.getElementById("mouse-circle").style.top = y - 15 + "px";
            document.getElementById("mouse-circle").style.left = document.documentElement.scrollLeft + x - 20 + "px";
            if (transformedX > 0) {
              document.documentElement.scrollLeft = document.documentElement.scrollLeft + 0.01*x;
            }
            if (transformedX < 0) {
              document.documentElement.scrollLeft = document.documentElement.scrollLeft - 0.01*x;
            }
        }
</script>

但问题是:如果我的鼠标不动,它也不会移动屏幕。所以我想:为什么不放一个

代码语言:javascript
复制
while (transformedX > 0) {
    document.documentElement.scrollLeft = document.documentElement.scrollLeft + 0.01 * x;
}

出于某种原因,这破坏了一切,我不知道为什么。是否有更好的方法总是在鼠标位置上更新页面的scrollLeft?以下是整个代码:

代码语言:javascript
复制
const width = window.innerWidth;
const height = window.innerHeight;
const windowCenterX = width / 2;
const windowCenterY = height / 2;
document.onmousemove = function(e) {
  var x = e.clientX;
  var y = e.clientY;
  const transformedX = x - windowCenterX;
  document.getElementById("mouse-value").innerHTML = transformedX;
  document.getElementById("mouse-circle").style.top = y - 15 + "px";
  document.getElementById("mouse-circle").style.left = document.documentElement.scrollLeft + x - 20 + "px";
  if (transformedX > 0) {
    document.documentElement.scrollLeft = document.documentElement.scrollLeft + 0.01 * x;
  }
  if (transformedX < 0) {
    document.documentElement.scrollLeft = document.documentElement.scrollLeft - 0.01 * x;
  }
  while (transformedX > 0) {
    document.documentElement.scrollLeft = document.documentElement.scrollLeft + 0.01 * x;
  }
}
代码语言:javascript
复制
* {
  margin: 0px;
  padding: 0px;
}

html,
body {
  height: 100% !important;
}

#main-content {
  height: 100% !important;
  width: 9000px;
  background-image: linear-gradient(to right, #fff, #000);
}

#mouse-circle {
  position: absolute;
  z-index: 100;
  height: 40px;
  width: 40px;
  background-color: black;
  border: 1px solid white;
  border-radius: 100px;
}

body::-webkit-scrollbar {}

#right-arrow {
  height: 70px;
  width: 70px;
  background-color: black;
  border: 1px solid white;
  border-radius: 100px;
  position: absolute;
  left: 90%;
  top: 45%;
}

#mouse-position {
  height: 20px;
  width: 50px;
  border: 1px solid black;
  text-align: center;
  position: absolute;
  left: 80%;
}
代码语言:javascript
复制
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">

<div id="mouse-circle"></div>

<div id="main-content">
  <div id="right-arrow">
    <i style="color: white; margin: 35%;font-size: 25px;" class="fa fa-arrow-right" aria-hidden="true"></i>
  </div>
  <div id="mouse-position">
    <p id="mouse-value">0</p>
  </div>
</div>

谢谢您抽时间见我。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-01 10:25:22

scrollTo/Left/Top无法处理十进制值。

我会以一种不同的方式去做:

  • On "pointermove"只调用一个计算X方向和Y方向速度的函数。这些值是两个浮动值,从0.0到1.0.
  • 在循环requestAnimationFrame中移动区域.

X和Y的速度只在Viewport元素内的特定填充区域中计算,以便使指针在视图端口的中间休息,而不移动区域。这是由变量padd (从0.0到0.5)确定的。

为了使每个区域子元素都可以用指针到达,而不需要区域移动-该区域需要能够最大限度地移动,直到其中一个边缘接触到视口中心。

使用CSS transform: translate(-50%, -50%) translate3d(offsetX, offsetY, 0);按相对于其中心的偏移量移动该区域。

概念证明:

代码语言:javascript
复制
const elView = document.querySelector("#view");
const elArea = document.querySelector("#area");
const padd = 0.4; // Reactive padding pointer area (0.0 min to 0.5 max) 
const maxMove = 5; // px
const speed = {x: 0, y: 0};
const offset = {x: 0, y: 0};

const updatePos = (evt) => {
  const bcrView = elView.getBoundingClientRect();
  const x = Math.min(1, Math.max(0, (evt.clientX - bcrView.left) / bcrView.width));
  const y = Math.min(1, Math.max(0, (evt.clientY - bcrView.top) / bcrView.height));
  speed.x = 0;
  speed.y = 0;
  if (x < padd) {
    speed.x = (x / padd) - 1;
  } else if (x > (1 - padd)) {
    speed.x = (x - (1 - padd)) / padd;
  }
  if (y < padd) {
    speed.y = (y / padd) - 1;
  } else if (y > (1 - padd)) {
    speed.y = (y - (1 - padd)) / padd;
  }
};

const moveArea = () => {
  const bcrArea = elArea.getBoundingClientRect();
  const w2 = bcrArea.width / 2;
  const h2 = bcrArea.height / 2;
  offset.x -= speed.x * maxMove;
  offset.y -= speed.y * maxMove;
  offset.x = Math.max(-w2, Math.min(w2, offset.x));
  offset.y = Math.max(-h2, Math.min(h2, offset.y));
  elArea.style.transform = `translate(-50%, -50%) translate3d(${offset.x}px, ${offset.y}px, 0)`;
  requestAnimationFrame(moveArea);
};

requestAnimationFrame(moveArea);

elView.addEventListener("pointermove", updatePos);
elView.addEventListener("pointerleave", () => {
  speed.x = 0;
  speed.y = 0;
});
代码语言:javascript
复制
* {
  margin: 0;
  box-sizing: border-box;
}

body {
  display: flex;
  overflow: hidden;
}

#view {
  width: 100vw;
  height: 100vh;
  margin: auto;
  background: #000;
  overflow: hidden;
  touch-action: none;
}

#area {
  position: relative;
  width: calc(50px * 20);
  height: calc(50px * 16);
  background-color: #e5e5f7;
  opacity: 0.8;
  background-image: linear-gradient(#444cf7 2px, transparent 2px), linear-gradient(90deg, #444cf7 2px, transparent 2px), linear-gradient(#444cf7 1px, transparent 1px), linear-gradient(90deg, #444cf7 1px, #e5e5f7 1px);
  background-size: 50px 50px, 50px 50px, 10px 10px, 10px 10px;
  background-position: -2px -2px, -2px -2px, -1px -1px, -1px -1px;
  top: 50%;
  left: 50%;
  transform: translate(-100%, -100%);
}

.centerDot {
  position: absolute;
  background: red;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
代码语言:javascript
复制
<div id="view">
  <div id="area">
    <div class="centerDot"></div>
  </div>
  <div class="centerDot"></div>
</div>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72813428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档