3

我正在使用Web Animation API创建一个简单的动画,这样当用户在鼠标上移动时target,动画应该从左到右开始,当用户将鼠标移开时target,动画应该反转并且target应该从右到左。

目前,如果用户在动画过程中将鼠标移入/移出,动画会很生涩,而且我没有平滑的效果。

我想知道如何解决这个问题。

注意:目前我正在使用 Web Animation 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>

4

3 回答 3

1

我一直使用mouseenter / mouseleave而不是mouseover / mouseout取得成功。

尽管它们的操作方式相同,但是该mouseenter事件仅在鼠标指针进入所选元素时触发。mouseover如果鼠标指针也进入任何子元素,则触发该事件。

于 2016-11-21T13:40:30.610 回答
0

我能够使用以下脚本添加一些逻辑来解决这个问题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>

于 2016-11-21T14:10:45.870 回答
0

每次触发 mouseover 事件时,您都会为元素制作一个新动画。通过预先创建动画并暂停它直到使用它来避免这种情况。

我也换成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 事件不会触发。它仅在鼠标移动时触发。

于 2016-11-21T14:35:52.683 回答