如何在touchmove事件中使用绝对定位一致地移动一个居中的元素?

huangapple go评论76阅读模式
英文:

How to move a centered element consistently with absolute positioning on touchmove event?

问题

我不知道如何在每次滑动时将元素的更改坐标保留在内存中。这很难做,因为该元素的位置是绝对定位且居中的。是否有任何方法可以获取该元素的当前坐标?

这是一个示例 Codepen中的示例

const swipeDiv = document.querySelector(".swipe");

swipeDiv.addEventListener("touchstart", handleTouchStart);
swipeDiv.addEventListener("touchmove", handleTouchMove);

let x1 = null;
let y1 = null;
let x2 = null;
let y2 = null;

function handleTouchStart(event) {
  const firstTouch = event.touches[0];
  if (x1 === null || y1 === null) {
    x1 = firstTouch.clientX;
    y1 = firstTouch.clientY;
  }
}

function handleTouchMove(event) {
  event.preventDefault();
  if (x1 === null || y1 === null) return false;
  window.scrollTo(window.pageXOffset, window.pageYOffset);
  x2 = event.touches[0].clientX;
  y2 = event.touches[0].clientY;
  let xDiff = x2 - x1;
  let yDiff = y2 - y1;

  this.style.transform = `translate(${-this.clientWidth / 2 + xDiff}px, ${
    -this.clientHeight / 2 + yDiff
  }px) rotate(-20deg)`;

  x1 = `${-this.clientWidth/2 + xDiff}`;
  y1 = `${-this.clientHeight/2 + yDiff}`;
}
body {
  width: 100vw;
  height: 200vh;
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
  font-size: 1.2rem;
  background: pink;
}

.wrapper {
  position: relative;
  overflow: hidden;
  width: 200px;
  height: 150px;
  margin-top: 200px;
  background: #ccc;
}

.swipe {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-20deg);
  display: flex;
  justify-content: center;
  align-items: center;
  width: 400px;
  height: 300px;
  background: rgba(255, 0, 0, .5);
}
<div class="wrapper">
  <div class="swipe">Testing touchmove</div>
</div>

我尝试了,但失败了。非常感谢。

英文:

I can't figure out how to keep in memory changed coordinates of the element every time I swipe.
This is difficult to do it cause the element is absolutely positioned and centered. Is there any way to get the current coordinates of the el?

Here is an ex here in Codepen

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const swipeDiv = document.querySelector(&quot;.swipe&quot;);
// console.log(swipeDiv.getBoundingClientRect().x);

swipeDiv.addEventListener(&quot;touchstart&quot;, handleTouchStart);
swipeDiv.addEventListener(&quot;touchmove&quot;, handleTouchMove);

let x1 = null;
let y1 = null;
let x2 = null;
let y2 = null;

function handleTouchStart(event) {
  const firstTouch = event.touches[0];
  if (x1 === null || y1 === null) {
    x1 = firstTouch.clientX;
    y1 = firstTouch.clientY;
  }
}

function handleTouchMove(event) {
  event.preventDefault();
  if (x1 === null || y1 === null) return false;
  window.scrollTo(window.pageXOffset, window.pageYOffset);
  x2 = event.touches[0].clientX;
  y2 = event.touches[0].clientY;
  let xDiff = x2 - x1;
  let yDiff = y2 - y1;

  this.style.transform = `translate(${-this.clientWidth / 2 + xDiff}px, ${
    -this.clientHeight / 2 + yDiff
  }px) rotate(-20deg)`;

  x1 = `${-this.clientWidth/2 + xDiff}`;
  y1 = `${-this.clientHeight/2 + yDiff}`;
}

<!-- language: lang-css -->

body {
  width: 100vw;
  height: 200vh;
  margin: 0;
  pading: 0;
  display: flex;
  justify-content: center;
  font-size: 1.2rem;
  background: pink;
}

.wrapper {
  position: relative;
  overflow: hidden;
  width: 200px;
  height: 150px;
  margin-top: 200px;
  background: #ccc;
}

.swipe {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-20deg);
  display: flex;
  justify-content: center;
  align-items: center;
  width: 400px;
  height: 300px;
  background: rgba(255, 0, 0, .5);
}

<!-- language: lang-html -->

&lt;div class=&quot;wrapper&quot;&gt;
  &lt;div class=&quot;swipe&quot;&gt;Testing touchmove&lt;/div&gt;
&lt;/div&gt;

<!-- end snippet -->

I tried but I failed.
Thanks a lot.

答案1

得分: 1

一种方法是在 handleTouchStart 函数中从 x1 中减去 xDiff,从 y1 中减去 yDiff。只需确保在全局范围内将它们初始化为零,以便我们可以使用它们。代码如下:

function handleTouchStart(event) {
  const firstTouch = event.touches[0];
  x1 = firstTouch.clientX - xDiff;
  y1 = firstTouch.clientY - yDiff;
}

示例:https://codepen.io/Dodekus/pen/xxJoWoQ

英文:

One way to do it is to subtract xDiff from x1 and yDiff from y1 in handleTouchStart. Just make sure to initialize these to zero globally first so we can use them. This is how it should look:

function handleTouchStart(event) {
  const firstTouch = event.touches[0];
  x1 = firstTouch.clientX - xDiff;
  y1 = firstTouch.clientY - yDiff;
}

Example: https://codepen.io/Dodekus/pen/xxJoWoQ

huangapple
  • 本文由 发表于 2023年2月10日 06:16:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/75405024.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定