【问题标题】:Clipping an absolute child that is animated剪裁动画的绝对孩子
【发布时间】:2018-02-19 04:00:20
【问题描述】:

我四处寻找答案,发现我应该使用position: relative; 来纠正我的情况。但是,它似乎不适用于我的情况。我正在使用 JQuery 和 AnimeJS。从本质上讲,我想要实现的是 Google 使用 AnimeJS 在他们的按钮上产生的涟漪效应。

如果我没有立即回复,请提前致谢。

function ripple(event) {
  //Find cursor position
  var x = event.pageX,
    y = event.pageY;
  if ($(".ripple").length > 0) { //If there is already a div for the ripple
    //Remove previous ripple
    $(".ripple").remove();

    $("div.btn").append("<div class='ripple'></div>"); //Append a div with the class ripple
    $(".ripple").css({
      "top": y - 20,
      "left": x - 20
    }); //Position the div so that it is on the cursor
    var ripple = anime({ //Ripple Animation
      targets: ".ripple",
      opacity: {
        value: [1, 0],
        duration: 2000
      },
      scale: {
        value: 10,
        duration: 3000
      },
    });
    $(".ripple").delay(2000).queue(function() {
      $(this).remove();
    }); //Delete div at the end of the animation
  } else {
    $("div.btn").append("<div class='ripple'></div>"); //Append a div with the class ripple
    $(".ripple").css({
      "top": y - 20,
      "left": x - 20
    }); //Position the div so that it is on the cursor
    var ripple = anime({ //Ripple Animation
      targets: ".ripple",
      opacity: {
        value: [1, 0],
        duration: 2000
      },
      scale: {
        value: 10,
        duration: 3000
      },
    });
    $(".ripple").delay(3000).queue(function() {
      $(this).remove();
    }); //Delete div at the end of the animation
  }
}
html {
  background: #d6d7d8;
  height: 100%;
  width: 100%;
}

body {
  height: 100%;
  width: 100%;
  display: grid;
  grid-template-columns: 2fr 1fr 2fr;
  grid-template-rows: 2fr 1fr 2fr;
}

.btn {
  grid-column-start: 2;
  grid-column-end: 2;
  grid-row-start: 2;
  grid-row-end: 2;
  background: #ff5722;
  border-radius: 10px;
  box-shadow: 0 10px 20px 4px #aaaaaa;
  cursor: pointer;
  overflow: hidden;
  outline: none;
  border: none;
  position: relative;
}

.ripple {
  pointer-events: none;
  position: absolute;
  border-radius: 50%;
  height: 40px;
  width: 40px;
  background: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
<div class="btn" onclick="ripple(event)"></div>

【问题讨论】:

    标签: javascript jquery html css anime.js


    【解决方案1】:

    如果我正确理解问题,通过将 x & y 设置为 event.pageX / pageY 不会考虑父按钮的位置。因此,如果 pageX = 200 发生的事情是您将 CSS 设置为 left: 200px 相对于父级。父级只有 80px 宽,所以它会超出父级容器。

    为了说明父级,您可以分别从 event.pageX 和 pageY 中减去父级按钮的 offsetLeftoffsetTop

      var x = event.pageX - $btn.offsetLeft,
          y = event.pageY - $btn.offsetTop;
    

    我对你原来的 JS 做了一些清理。一般来说,您不想重复自己,看起来 else 语句中的所有代码都没有必要。

    若要在未来调试此类问题,可能会更容易一步一步完成,并在添加动画之前查看所有内容是否符合您的预期。例如,通过删除动画并仅查看 .ripple 元素的位置,我可以很快看到它超出了它需要的位置。

    function ripple(event) {
      var $btn = $("div.btn");
      var $ripple = $(".ripple");
    
      //Find cursor position
      var x = event.pageX - $btn.offsetLeft,
        y = event.pageY - $btn.offsetTop;
    
      //If there is already a div for the ripple
      if ($ripple.length > 0) {
        //Remove previous ripple
        $ripple.remove();
      }
    
      //Append a div with the class ripple
      $ripple = $('<div class="ripple"></div>');
      $btn.append($ripple);
    
      //Position the div so that it is on the cursor
      $ripple.css({
        "top": y,
        "left": x
      });
    
      //Ripple Animation
      var ripple = anime({
        targets: ".ripple",
        opacity: {
          value: [1, 0],
          duration: 2000
        },
        scale: {
          value: 10,
          duration: 3000
        },
      });
    
      //Delete div at the end of the animation
      $ripple.delay(2000).queue(function() {
        $(this).remove();
      });
    }
    html {
      background: #d6d7d8;
      height: 100%;
      width: 100%;
    }
    
    body {
      height: 100%;
      width: 100%;
      display: grid;
      grid-template-columns: 2fr 1fr 2fr;
      grid-template-rows: 2fr 1fr 2fr;
    }
    
    .btn {
      grid-column-start: 2;
      grid-column-end: 2;
      grid-row-start: 2;
      grid-row-end: 2;
      background: #ff5722;
      border-radius: 10px;
      box-shadow: 0 10px 20px 4px #aaaaaa;
      cursor: pointer;
      overflow: hidden;
      outline: none;
      border: none;
      position: relative;
    }
    
    .ripple {
      pointer-events: none;
      position: absolute;
      border-radius: 50%;
      height: 40px;
      width: 40px;
      background: white;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
    <div class="btn" onclick="ripple(event)"></div>

    【讨论】:

    • 我运行了代码 sn-p 并且看起来波纹没有移动到光标在按钮中的位置。但是,您创建的效果正是我想要通过剪辑实现的效果。
    • 更新:我自己跑了,发现当我点击屏幕时变量 x 和 y 返回 NaN。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-29
    • 1970-01-01
    • 2017-02-26
    相关资源
    最近更新 更多