Запаздывающая/заикающаяся тень окна производительности в зависимости от положения мыши

#javascript #css

Вопрос:

Я закодировал отбрасывание тени в поле для изображений в моем элементе, где оно будет реагировать на положение мыши. Это хорошо работает, если эффект тени коробки должен выполняться только на одном элементе. Однако при работе с несколькими элементами он начинает запаздывать/заикаться. Мне неясно, что является причиной этого. Я надеюсь, что кто-нибудь сможет это прояснить.

Вот короткое видео того, что я испытываю:- https://drive.google.com/file/d/1ULahZWR5sKt-yaDEIjEvK3TFa1g1n65d/view

Прилагается мой код;

HTML:

 <div class="header-image">
   <img class="images shadow-effect" src="./images/baby-swimming-classes.jpg" alt="Baby Swimming Class">
   <img class="images shadow-effect" src="./images/children-swimming-classes.jpg" alt="Children Swimming Class">
   <img class="images shadow-effect" src="./images/pre-competitive-swimming-classes.jpg" alt="Pre-Competitive Swimming Class">
   <img class="images shadow-effect" src="./images/adult-swimming-classes.jpg" alt="Adult Swimming Class">
</div>
 

Язык JavaScript:

 $(document).ready(function() {

const eleShadow = Object.values($('.shadow-effect'));
const shadowMax = 20; //px

// 1. Getting the required information
function boxShadow(e) {

    //Screen width and height
    const {
        width: screenWidth,
        height: screenHeight
    } = screen;

    //Mouse position
    const {
        clientX: mouseX,
        clientY: mouseY
    } = e;

    //Position of objects
    const {
        x: eleX,
        y: eleY,
        width: eleWidth,
        height: eleHeight
    } = eleShadow[0].getBoundingClientRect();

    const shadowX = (((eleX   (eleWidth / 2)) - mouseX) / screenWidth) * shadowMax;
    const shadowY = (((eleY   (eleHeight / 2)) - mouseY) / screenHeight) * shadowMax;

    // eleShadow[0].style.boxShadow = `${shadowX}px ${shadowY}px 0 #EF5B5B`;

    $(".shadow-effect").css("box-shadow",
        `${shadowX}px ${shadowY}px 0 #EF5B5B`
    );

    // For each individual element

}

$(document).on('mousemove', boxShadow);
})
 

Обновить:-
Это сглаживает до 3 изображений, когда появляется 4-е изображение. Он начинает отставать. Однако иногда 4 изображения выглядят гладко, но когда я обновляю их, они могут снова заикаться.

Ответ №1:

Слишком много событий срабатывает, так как это mousemove событие включено document . Попробуйте немного снизить скорость срабатывания триггеров.

 /* eslint-disable no-undef*/

$(document).ready(function () {
  const eleShadow = Object.values($(".shadow-effect"));
  const shadowMax = 20; //px

  // Throttle function: Input as function which needs to be throttled and delay is the time interval in milliseconds
  let timerId;
  const throttleFunction = (func, delay) => {
    // If setTimeout is already scheduled, no need to do anything
    if (timerId) {
      return;
    }

    // Schedule a setTimeout after delay seconds
    timerId = setTimeout(function () {
      func();

      // Once setTimeout function execution is finished, timerId = undefined so that in <br>
      // the next scroll event function execution can be scheduled by the setTimeout
      timerId = undefined;
    }, delay);
  };

  // 1. Getting the required information
  function boxShadow(e) {
    //Screen width and height
    const { width: screenWidth, height: screenHeight } = window.screen;

    //Mouse position
    const { clientX: mouseX, clientY: mouseY } = e;

    //Position of objects
    const {
      x: eleX,
      y: eleY,
      width: eleWidth,
      height: eleHeight
    } = eleShadow[0].getBoundingClientRect();

    const shadowX = ((eleX   eleWidth / 2 - mouseX) / screenWidth) * shadowMax;
    const shadowY =
      ((eleY   eleHeight / 2 - mouseY) / screenHeight) * shadowMax;

    // eleShadow[0].style.boxShadow = `${shadowX}px ${shadowY}px 0 #EF5B5B`;

    $(".shadow-effect").css(
      "box-shadow",
      `${shadowX}px ${shadowY}px 0 #EF5B5B`
    );

    // For each individual element
  }

  $(document).on("mousemove", (e) => throttleFunction(() => boxShadow(e), 50));
}); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Static Template</title>
  </head>
  <body>
    <div class="header-image">
      <img
        class="images shadow-effect"
        src="https://tinyjpg.com/images/social/website.jpg"
        alt="Baby Swimming Class"
        width="200"
      />
      <img
        class="images shadow-effect"
        src="https://tinyjpg.com/images/social/website.jpg"
        alt="Children Swimming Class"
        width="200"
      />
      <img
        class="images shadow-effect"
        src="https://tinyjpg.com/images/social/website.jpg"
        alt="Pre-Competitive Swimming Class"
        width="200"
      />
      <img
        class="images shadow-effect"
        src="https://tinyjpg.com/images/social/website.jpg"
        alt="Adult Swimming Class"
        width="200"
      />
    </div>
  </body>
</html> 

Вы можете поиграть с задержкой и найти оптимальное соотношение производительности и опыта

Комментарии:

1. Спасибо @Akhil, я попробую это сделать. Тем не менее, я понимаю, что может быть вызвано слишком много событий, но почему это нормально, когда у меня есть эффект на 3 изображениях, 1 элементе ввода и элементе кнопки, но он плохо работает на 4 изображениях.

2. Ха, это не работает. даже с таймаутом в 25 мс.. он все еще отстает/заикается. Может ли это быть проблемой с производительностью компьютера?

3. Я перестал использовать функцию эффекта тени и просто использую стиль теней в css, который меняется в направлении при нажатии … он также отстает. Не уверен, что функция больше не является проблемой, хм .

Ответ №2:

Я обнаружил, что проблема заикания/задержки связана не с JavaScript, а с размером файла. Из-за того, что размер файла одного из изображений слишком велик. Сжатие изображений помогло бы. Кроме того, сохранение изображений в качестве оригинальных со свойством и значением ниже также вызывает заикание.

 object-fit: cover; 
 

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