映射滚动值以更改rgba不透明度

时间:2018-06-11 16:18:19

标签: jquery scroll mapping viewport rgba

我想在用户滚动时改变div颜色的不透明度。

但它需要一些东西:

  • 检查div是否在视口中。用这段代码做到了:

    var scrollBottom = $(window).scrollTop() + $(window).height(),
    
        ideeHeight = $(this).offset().top;
    
        if (scrollBottom >= ideeHeight)
    
  • 滚动的值映射为0.0 - > 1.0值。这段代码:

    var docHeight = $(window).height(), opacity = map(ideeHeight, 0, docHeight, 0.0, 1.0);

  • 滚动时更改div颜色的不透明度。我试过这个:

    $(this).css("background", "rgba(255, 255, 255," + opacity + ")");

这似乎不起作用。任何人都可以告诉我我在哪里犯了错误,或者这根本不是正确的做法吗?谢谢!



$(window).on("scroll", function() {
  function map(num, in_min, in_max, out_min, out_max) {
    return (num - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  }

  $(".idee").each(function() {
    var scrollBottom = $(window).scrollTop() + $(window).height(),
      ideeHeight = $(this).offset().top;
    if (scrollBottom >= ideeHeight) {
        var docHeight = $(window).height(),
        opacity = map(ideeHeight, 0, docHeight, 0.0, 1.0);

      $(this).css("background", "rgba(255, 255, 255," + opacity + ")");
    }
  });
});

body {
  background: #cdd3d8;
  font-family: Helvetica;
}

.idee {
  display: flex;
  justify-content: space-around;
  align-items: center;
  width: 80vw;
  min-height: 50vh;
  margin: 2vw auto;
  padding: 1em;
  background: rgba(255, 255, 255, 0);
  box-shadow: 0px 2px 10px 2px grey;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
&#13;
&#13;
&#13;

如果它更容易,here也是一个jsfiddle链接。

1 个答案:

答案 0 :(得分:1)

由于您希望不透明度从0到1,map()函数应返回映射到输出值范围的输入值的比率,而不是映射的输出值本身。

根据您的评论,我使用Stanislav's answer here中的calculateVisibilityForDiv()函数计算视口中可见元素的比例。然后将不透明度设置为每个元素可见的比率(从0到1)。

&#13;
&#13;
var windowHeight = $(window).height();

function calculateVisibilityForDiv($elm) {

  var docScroll = $(document).scrollTop();
  var elmPosition = $elm.offset().top;
  var elmHeight = $elm.height();
  var hiddenBefore = docScroll - elmPosition;
  var hiddenAfter = (elmPosition + elmHeight) - (docScroll + windowHeight);

  if ((docScroll > elmPosition + elmHeight) || (elmPosition > docScroll + windowHeight)) {
    var result = 0;
  } else {
    var result = 1;

    if (hiddenBefore > 0) {
      result -= hiddenBefore / elmHeight;
    }

    if (hiddenAfter > 0) {
      result -= hiddenAfter / elmHeight;
    }

  }
  return result;

}

$(window).on("scroll", function() {

  $(".idee").each(function() {
    var $this = $(this);
    var opacity = calculateVisibilityForDiv($this);
    $this.css("background", "rgba(255, 255, 255," + opacity + ")");
  });

}).trigger('scroll');
&#13;
body {
  background: #cdd3d8;
  font-family: Helvetica;
}

.idee {
  display: flex;
  justify-content: space-around;
  align-items: center;
  width: 80vw;
  min-height: 50vh;
  margin: 2vw auto;
  padding: 1em;
  background: rgba(255, 255, 255, 0);
  box-shadow: 0px 2px 10px 2px grey;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
&#13;
&#13;
&#13;

归因:
Stack Overflow How much of an element is visible in viewport;
tomanswered Stanislav提出。

编辑:
当元素离开视口时修改为不淡出。

&#13;
&#13;
var windowHeight = $(window).height();

function calculateVisibilityForDiv($elm) {

  var docScroll = $(document).scrollTop();
  var elmPosition = $elm.offset().top;
  var elmHeight = $elm.height();
  var hiddenAfter = (elmPosition + elmHeight) - (docScroll + windowHeight);
  var ratio = 1 - (hiddenAfter / elmHeight);
  return ratio > 0 ? (ratio < 1 ? ratio : 1) : 0;

}

$(window).on("scroll", function() {

  $(".idee").each(function() {
    var $this = $(this);
    var opacity = calculateVisibilityForDiv($this);
    $this.css("background", "rgba(255, 255, 255," + opacity + ")");
  });

}).trigger('scroll');
&#13;
body {
  background: #cdd3d8;
  font-family: Helvetica;
}

.idee {
  display: flex;
  justify-content: space-around;
  align-items: center;
  width: 80vw;
  min-height: 50vh;
  margin: 2vw auto;
  padding: 1em;
  background: rgba(255, 255, 255, 0);
  box-shadow: 0px 2px 10px 2px grey;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
<div class="idee">
  <p>Hello World</p>
</div>
&#13;
&#13;
&#13;