анимация mojs, стреляющая в старое местоположение объекта после прокрутки - PullRequest
0 голосов
/ 29 марта 2019

https://codepen.io/mprquinn/pen/OmOMrR/
credit: Mike Quinn

Следующий код запускает анимацию при наведении курсора на ссылку.Как я понимаю в коде, координаты x и y должны обновлять позицию при каждом вызове функции, так как getBoundingClientRect () должен обновлять координаты при прокрутке документа ...

Если вы наводите курсор мышиПо ссылке, не прокручивая страницу, анимация будет окружать ссылку, как и предполагалось, но если документ прокручивается, анимация запускается над ссылкой.В консоли я замечаю, что X и Y не обновляются, когда документ прокручивается и вызывается getBoundingClientRect () ...

const links = document.querySelectorAll('a');
    links.forEach(link => link.addEventListener('mouseenter', shootLines));    

    function shootLines(e) {    
      const itemDim = this.getBoundingClientRect(),
            itemSize = {
              x: itemDim.right - itemDim.left,
              y: itemDim.bottom - itemDim.top,
            },
            shapes = ['line'],
            colors = ['#2FB5F3',
                      '#FF0A47',
                      '#FF0AC2',
                      '#47FF0A'];
      
      const chosenC = Math.floor(Math.random() * colors.length),
            chosenS = Math.floor(Math.random() * shapes.length);
      
      // create shape
      const burst = new mojs.Burst({
        left: itemDim.left + (itemSize.x/2),
        top: itemDim.top + (itemSize.y/2),
        radiusX: itemSize.x,
        radiusY: itemSize.y,
        count: 8,
        
        children: {
          shape: shapes[chosenS],
          radius: 10,
          scale: {0.8: 1},
          fill: 'none',
          points: 7,
          stroke: colors[chosenC],
          strokeDasharray: '100%',
          strokeDashoffset: { '-100%' : '100%' },
          duration: 450,
          delay: 100,
          easing: 'quad.out',
          isShowEnd: false,
        }
      });
      
      burst.play();
    }
.container {
  margin-top: 20%;
  height: 110vh;
}
<div class="container"><a href="javascript:void(0);">test</a></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mo-js/0.288.2/mo.min.js"></script>

1 Ответ

1 голос
/ 31 марта 2019

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

Проблема, с которой вы столкнулись, заключается в том, что вы используете getBoundingClientRect, который дает координаты области просмотра элемента.Пакет, по умолчанию, работает от элемента тела документа (координаты документа).Координаты документа элемента ссылки никогда не меняются при прокрутке, а координаты области просмотра.См. здесь для простого объяснения.

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

const links = document.querySelectorAll('a');
    links.forEach(link => {    
      const itemDim = link.getBoundingClientRect(),
            itemSize = {
              x: itemDim.right - itemDim.left,
              y: itemDim.bottom - itemDim.top,
            },
            shapes = ['line'],
            colors = ['#2FB5F3',
                      '#FF0A47',
                      '#FF0AC2',
                      '#47FF0A'];
      
      const chosenC = Math.floor(Math.random() * colors.length),
            chosenS = Math.floor(Math.random() * shapes.length);
      
      // create shape
      const burst = new mojs.Burst({
        left: itemDim.left + (itemSize.x/2),
        top: itemDim.top + (itemSize.y/2),
        radiusX: itemSize.x,
        radiusY: itemSize.y,
        count: 8,
        
        children: {
          shape: shapes[chosenS],
          radius: 10,
          scale: {0.8: 1},
          fill: 'none',
          points: 7,
          stroke: colors[chosenC],
          strokeDasharray: '100%',
          strokeDashoffset: { '-100%' : '100%' },
          duration: 450,
          delay: 100,
          easing: 'quad.out',
          isShowEnd: false,
        }
      });

      // Add the mouseenter listener to play the burst.
      link.addEventListener('mouseenter', function () { burst.play(); });
    });
.container {
  margin-top: 20%;
  height: 110vh;
}
<div class="container"><a href="javascript:void(0);">test</a></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mo-js/0.288.2/mo.min.js"></script>
...