Избегайте рывков при наведении и наведении курсора мыши

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

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

Хотелось бы узнать, как решить эту проблему.

Примечание. В настоящее время я использую API веб-анимации. Но та же проблема возникает при использовании анимации ключевых кадров CSS.

Я также попытался решить эту проблему, используя следующее решение, которое улучшило ситуацию, но это все еще проблематично. Вот живой пример https://jsfiddle.net/x784xwoa/5/

var elm = document.getElementById("target");
var player = document.getElementById("target");

elm.addEventListener('mouseover', function(event) {
  console.log('mouseover', player.playState, 'animate');
  player = elm.animate(
    [{
      left: "0px",
      boxShadow: 'rgba(0, 0, 0, 0.5) 0px 0px 0px 0px'
    }, {
      left: "100px",
      boxShadow: 'rgba(0, 0, 0, 0.9) 50px 150px 100px 0px'
    }], {
      duration: 3000,
      direction: "normal",
      fill: "forwards",
      iterations: 1
    }
  );
});

elm.addEventListener('mouseout', function(event) {
  console.log('mouseout', player.playState, 'reverse');
  player.reverse();
});
#target {
  position: relative;
  top: 0;
  left: 0;
  width: 100px;
  height: 150px;
  background-color: red;
}
<div id="target"></div>


person GibboK    schedule 21.11.2016    source источник
comment
Что вы замечаете при использовании обновленного кода? В настоящее время и Chrome, и Firefox реализуют аддитивную анимацию (часть веб-анимации), которая позволит вам создавать одну анимацию, плавно переходящую в другую.   -  person brianskold    schedule 22.11.2016


Ответы (3)


Мне всегда удавалось использовать mouseenter / mouseleave, а не mouseover / mouseout.

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

person rfornal    schedule 21.11.2016
comment
Спасибо за ваш комментарий, я попробовал ваше предложение, к сожалению, у меня все еще есть та же проблема jsfiddle.net/r39f461s/2 - person GibboK; 21.11.2016

Мне удалось решить эту проблему, используя следующий сценарий, добавляющий логику для проверки playState. Если у вас есть лучшее решение, опубликуйте его в качестве ответа, так как мне было бы очень интересно получить ваш отзыв.

   document.addEventListener("DOMContentLoaded", function (event) {
            var elm = document.getElementById("target");
            var player = null;



            elm.addEventListener('mouseenter', function (event) {
                if (player === null) {
                    player = elm.animate(
                      [{
                          left: "0px",
                          boxShadow: 'rgba(0, 0, 0, 0.5) 0px 0px 0px 0px'
                      }, {
                          left: "100px",
                          boxShadow: 'rgba(0, 0, 0, 0.9) 50px 150px 100px 0px'
                      }], {
                          duration: 3000,
                          direction: "normal",
                          fill: "forwards",
                          iterations: 1
                      }
                    );
                }
                else if (player.playState === 'running') {
                    player.reverse();
                }
                else if (player.playState === 'finished') {
                    player.reverse();

                }
            });

            elm.addEventListener('mouseout', function (event) {
                if (player.playState === 'running' || player.playState === 'finished') {
                    player.reverse();
                }
            });

            setInterval(function () {
                if (player) {
                    console.log(player.playState);
                }
            }, 1000);


        });
        #target {
            position: relative;
            top: 0;
            left: 0;
            width: 100px;
            height: 150px;
            background-color: red;
        }
    <div id="target"></div>

person GibboK    schedule 21.11.2016

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

Я также заменил player.reverse(); на player.playBackRate = (-)1;. Я не уверен, почему это тоже вызвало проблемы.

var elm = document.getElementById("target");
var player = elm.animate(
  [{
    left: "0px",
    boxShadow: 'rgba(0, 0, 0, 0.5) 0px 0px 0px 0px'
  }, {
    left: "100px",
    boxShadow: 'rgba(0, 0, 0, 0.9) 50px 150px 100px 0px'
  }], {
    duration: 3000,
    direction: "normal",
    fill: "forwards",
    iterations: 1
  }
);
player.pause();

elm.addEventListener('mouseover', function(event) {
  player.playbackRate = 1;
  player.play();
});

elm.addEventListener('mouseout', function(event) {
  player.playbackRate = -1;
});
#target {
  position: relative;
  top: 0;
  left: 0;
  width: 100px;
  height: 150px;
  background-color: red;
}
<div id="target"></div>

Единственная проблема, которая остается, заключается в том, что событие mouseout не срабатывает, когда элемент перемещается из-под мыши. Он срабатывает только при перемещении мыши.

person Floris    schedule 21.11.2016