тег html сдвигается в chrome при анимации

Рейтинг: 0Ответов: 0Опубликовано: 29.04.2023

Написал функцию для анимации при доскроливании до элемента. Проблема в том, что почему-то тег html сдвигается иногда, не понимаю, почему такая проблема. Замечаю это в Chrome. Пробовал в Firefox, не наблюдал эту проблему

function isElementInViewport(element) {
  const rect = element.getBoundingClientRect();
  const windowHeight =
    window.innerHeight || document.documentElement.clientHeight;
  const windowWidth =
    window.innerWidth || document.documentElement.clientWidth;

  return (
    rect.top >= 0 &&
    rect.left >= 0 &&
    rect.bottom <= windowHeight &&
    rect.right <= windowWidth
  );
}

function observeElement({
  node,
  cb,
  cbOnce
}) {
  cbOnce(node);

  if (isElementInViewport(node)) {
    cb(node);
    return;
  }

  const observer = new IntersectionObserver((entries, observer) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        cb(node);
        observer.disconnect();
      }
    });
  });

  observer.observe(node);
}

function getRandomDirection() {
  const directions = ['left', 'right', 'top', 'bottom'];
  const randomIndex = Math.floor(Math.random() * directions.length);
  return directions[randomIndex];
}

function getCoordsAnimByDirection(direction, shift) {

  const matchObj = {
    left: {
      x: -shift
    },
    right: {
      x: shift
    },
    top: {
      y: -shift
    },
    bottom: {
      y: shift
    }
  };

  if (direction === 'random') {
    direction = getRandomDirection();
  }

  for (const matchObjDir in matchObj) {
    const matchObjItem = matchObj[matchObjDir];
    if (matchObjDir === direction) {
      return matchObjItem;
    }
  }

  throw new Error(`animateOnScroll -> getCoordsAnimByDirection: неправильное направление ${direction}`);
}


function animateOnScroll({
  node,
  direction,
  cb = () => {},
  duration = 1,
  shift = 200
}) {
  const coordsAnim = getCoordsAnimByDirection(direction, shift);

  observeElement({
    node: node,
    cbOnce: () => {
      gsap.set(node, {
        opacity: 0,
        ...coordsAnim
      });
    },
    cb: () => {
      cb(node);
      gsap.to(node, {
        opacity: 1,
        y: 0,
        x: 0,
        duration: duration
      });
    },
  });
}


const pNodes = document.querySelectorAll('.paragraph');

function randomAnimsOnScroll(nodes) {

  for (const node of nodes) {
    animateOnScroll({
      node: node,
      direction: 'random'
    });
  }

}

randomAnimsOnScroll([...pNodes]);
@import url('https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap');
*,
*::before,
*::after {
  box-sizing: inherit;
}

html {
  box-sizing: border-box;
}

:root {
  --bgColor: white;
  --color: rgb(34, 34, 34);
}

@media (prefers-color-scheme: dark) {
   :root {
    --bgColor: rgb(34, 34, 34);
    --color: white;
  }
}

.container {
  max-width: 1000px;
  padding: 0 15px;
  margin: 0 auto;
  display: block;
  width: 100%;
}

body {
  margin: 0;
  color: var(--color);
  background-color: var(--bgColor);
  font-family: 'Ubuntu', sans-serif;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  padding: 100px 0;
}

.paragraph {
    padding: 5rem 0;
    margin: 0;
    font-size: 2em;
}

.paragraph:nth-of-type(2n) {
  text-align: left;
}

.paragraph:nth-of-type(2n+1) {
  text-align: right;
}

.paragraph:nth-of-type(3n) {
  text-align: center;
}
<div class="container">
  <p class="paragraph">Привет, это 1 блок</p>
  <p class="paragraph">Привет, это 2 блок</p>
  <p class="paragraph">Привет, это 3 блок</p>
  <p class="paragraph">Привет, это 4 блок</p>
  <p class="paragraph">Привет, это 5 блок</p>
  <p class="paragraph">Привет, это 6 блок</p>
  <p class="paragraph">Привет, это 7 блок</p>
  <p class="paragraph">Привет, это 8 блок</p>
  <p class="paragraph">Привет, это 9 блок</p>
  <p class="paragraph">Привет, это 10 блок</p>
  <p class="paragraph">Привет, это 11 блок</p>
  <p class="paragraph">Привет, это 12 блок</p>
  <p class="paragraph">Привет, это 13 блок</p>
  <p class="paragraph">Привет, это 14 блок</p>
  <p class="paragraph">Привет, это 15 блок</p>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>

В Chrome можно заметить эту ошибку легче, вроде, если выбрать направление анимации из правой стороны (у меня всегда сдвинуто, если анимирую из правой стороны):

function isElementInViewport(element) {
  const rect = element.getBoundingClientRect();
  const windowHeight =
    window.innerHeight || document.documentElement.clientHeight;
  const windowWidth =
    window.innerWidth || document.documentElement.clientWidth;

  return (
    rect.top >= 0 &&
    rect.left >= 0 &&
    rect.bottom <= windowHeight &&
    rect.right <= windowWidth
  );
}

function observeElement({
  node,
  cb,
  cbOnce
}) {
  cbOnce(node);

  if (isElementInViewport(node)) {
    cb(node);
    return;
  }

  const observer = new IntersectionObserver((entries, observer) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        cb(node);
        observer.disconnect();
      }
    });
  });

  observer.observe(node);
}

function getRandomDirection() {
  const directions = ['left', 'right', 'top', 'bottom'];
  const randomIndex = Math.floor(Math.random() * directions.length);
  return directions[randomIndex];
}

function getCoordsAnimByDirection(direction, shift) {

  const matchObj = {
    left: {
      x: -shift
    },
    right: {
      x: shift
    },
    top: {
      y: -shift
    },
    bottom: {
      y: shift
    }
  };

  if (direction === 'random') {
    direction = getRandomDirection();
  }

  for (const matchObjDir in matchObj) {
    const matchObjItem = matchObj[matchObjDir];
    if (matchObjDir === direction) {
      return matchObjItem;
    }
  }

  throw new Error(`animateOnScroll -> getCoordsAnimByDirection: неправильное направление ${direction}`);
}


function animateOnScroll({
  node,
  direction,
  cb = () => {},
  duration = 1,
  shift = 200
}) {
  const coordsAnim = getCoordsAnimByDirection(direction, shift);

  observeElement({
    node: node,
    cbOnce: () => {
      gsap.set(node, {
        opacity: 0,
        ...coordsAnim
      });
    },
    cb: () => {
      cb(node);
      gsap.to(node, {
        opacity: 1,
        y: 0,
        x: 0,
        duration: duration
      });
    },
  });
}


const pNodes = document.querySelectorAll('.paragraph');

function randomAnimsOnScroll(nodes) {

  for (const node of nodes) {
    animateOnScroll({
      node: node,
      direction: 'right'
    });
  }

}

randomAnimsOnScroll([...pNodes]);
@import url('https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap');
*,
*::before,
*::after {
  box-sizing: inherit;
}

html {
  box-sizing: border-box;
}

:root {
  --bgColor: white;
  --color: rgb(34, 34, 34);
}

@media (prefers-color-scheme: dark) {
   :root {
    --bgColor: rgb(34, 34, 34);
    --color: white;
  }
}

.container {
  max-width: 1000px;
  padding: 0 15px;
  margin: 0 auto;
  display: block;
  width: 100%;
}

body {
  margin: 0;
  color: var(--color);
  background-color: var(--bgColor);
  font-family: 'Ubuntu', sans-serif;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  padding: 100px 0;
}

.paragraph {
    padding: 5rem 0;
    margin: 0;
    font-size: 2em;
}

.paragraph:nth-of-type(2n) {
  text-align: left;
}

.paragraph:nth-of-type(2n+1) {
  text-align: right;
}

.paragraph:nth-of-type(3n) {
  text-align: center;
}
<div class="container">
  <p class="paragraph">Привет, это 1 блок</p>
  <p class="paragraph">Привет, это 2 блок</p>
  <p class="paragraph">Привет, это 3 блок</p>
  <p class="paragraph">Привет, это 4 блок</p>
  <p class="paragraph">Привет, это 5 блок</p>
  <p class="paragraph">Привет, это 6 блок</p>
  <p class="paragraph">Привет, это 7 блок</p>
  <p class="paragraph">Привет, это 8 блок</p>
  <p class="paragraph">Привет, это 9 блок</p>
  <p class="paragraph">Привет, это 10 блок</p>
  <p class="paragraph">Привет, это 11 блок</p>
  <p class="paragraph">Привет, это 12 блок</p>
  <p class="paragraph">Привет, это 13 блок</p>
  <p class="paragraph">Привет, это 14 блок</p>
  <p class="paragraph">Привет, это 15 блок</p>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>

Тут на stackoverflow в сниппете сложно увидеть эту ошибку.
Приложу скриншот для примера:

введите сюда описание изображения

Chrome почему-то решил, что мне нужно сдвинуть весь сайт на эти мои 200px, которые я использую в анимации. Было бы хорошо понять зачем он это делает и как от этого избавиться

UPD: написал хрому(первый раз), что это баг(может что придумают) https://bugs.chromium.org/p/chromium/issues/detail?id=1441261

Ответы

Ответов пока нет.