基于窗口滚动算法定位的盒子阴影

时间:2017-05-04 21:21:27

标签: javascript jquery html css math

我有这个业余函数,它根据window.scrollTop位置和元素偏移更改一组元素上的box-shadow。当用户从照片向上或向下滚动时,框阴影将分别向下或向上移动。所以它给出了视角的幻觉。当这些照片元素位于屏幕的中心时,盒子阴影居中。

现在它并不理想,我的意思是它不是非常对称且感觉不对。我知道这是因为我的黄金比例" (不是实际的Phy黄金比例,我只是将它用作变量名称)只是一个随机数。我知道有一种方法可以使用我的变量来正确设置它我只是无法想出它。寻找黄金比例(箱阴影垂直偏移)从大约-20到20,0居中时,似乎看起来没问题。

所以我的问题是,任何人都可以优化我的算法,以便盒阴影如上所述发生变化,但更真实吗?

  • 这应该只发生在某个垂直滚动窗口内 当照片不在屏幕上时已经运行了这个功能(已经很多实现了)
  • 盒子阴影的变化是微妙的,所以它上面或下面没有巨大的阴影。
  • 在我的真实代码中,我有另一个功能,可以将照片更改为与窗口大小调整宽度相同的高度。这里我的固定高度为160px。

这是我的代码(经过修改以提供准系统示例)。如果更干净,请随意从头开始重做我的功能。



var halfHeight;
var eleHalfHeight;
var scrollTop;
var photosOffset;
var profOffset
var distPhotos;
var goldenRatio;

$(window).scroll(function() {
  halfHeight = $(window).height() / 2;
  eleHalfHeight = $('.photo').height() / 2;
  scrollTop = $(window).scrollTop();
  photosOffset = $('.photos').offset().top - halfHeight + eleHalfHeight;
  distPhotos = (photosOffset - scrollTop);

  if (distPhotos < photosOffset && distPhotos > -photosOffset) {
    goldenRatio = distPhotos / 25;
    $('.photo-frame').css('box-shadow', '0px ' + (goldenRatio + 6) + 'px 4px 2px #c9c9c9');
  };

});
&#13;
* {
  box-sizing: border-box;
}

body {
  margin: 0;
}

.wrapper {
  display: flex;
  align-items: center;
  min-height: 500vh;
  background-color: #fff;
}

.photos {
  display: flex;
  width: 100%;
  justify-content: space-around;
  margin-bottom: 60px;
  background-color: #fff;
}

.photos .photo-frame {
  width: 25%;
  height: 160px;
  border: 20px solid whitesmoke;
  box-shadow: 0px 0px 4px 2px gray;
  background-color: #000;
}

.photos .photo-frame .photo {
  width: 100%;
  background-color: #000;
  z-index: 1;
  position: relative;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
  <section class="photos">
    <div class="photo-frame">
      <div class="photo"></div>
    </div>
    <div class="photo-frame">
      <div class="photo"></div>
    </div>
    <div class="photo-frame">
      <div class="photo"></div>
    </div>
  </section>
</div>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

perfect™吗? 不。

我比你更喜欢它吗? 一点点。

它对你有帮助吗? 我希望如此,因为我认为调整起来更容易 - 至少这是我的意图。你告诉我。

&#13;
&#13;
let wH = $(window).height(),
    sO = 210, // shadowOffset (px); 50 => from -25 to +25
    tO = 4,   // topOffset (px)  0 => vertical symmetry,
    lO = 4,   // leftOffset (px) 0 => horizontal symmetry
    moveshadow = function() {
      let diff = $(window).scrollTop() - $(this).offset().top,
        tOH = $(this)[0].offsetHeight,
        should = (-diff < wH) && (diff < tOH),
        factor = should ? 
          -((diff / wH + 1) / (1 + tOH / wH) - .5) * sO + tO : 
          0;
      if (should) {
        $(this).css({
          "box-shadow": lO +"px " +
            factor +
            "px 8px -2px rgba(0,0,0,.1), " + lO + "px " +
            (factor + sO / 20) +
            "px 17px 4px rgba(0,0,0,.07), " + lO + "px " +
            (factor - sO / 20) +
            "px 22px 8px rgba(0,0,0,.06), " + lO/2 + "px " +
            factor / 20 +
            "px 21px 1px rgba(0,0,0,.12)"
        })
      }
    };

$(window)
  .on('resize', function() {
    wH = $(window).height()
  })
  .on('scroll resize', function() {
    $('.photo-frame').each(moveshadow)
  })
&#13;
body {
  background-color: #fff;
  text-align: center;
}

.wrapper {
  padding: 120vh 30px;
}

.photos {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.photo {
  width: 20vw;
  height: 32.36vw;
  background-color: #eee;
}

.photo-frame {
  padding: 20px;
  border: 1px solid #eee;
  box-sizing: border-box;
}

@media(min-width: 1000px) {
  .wrapper {
    width: 900px;
    display: inline-block;
  }
  .photo {
    width: 200px;
    height: 323.6px;
    background-color: #eee;
  }
}
@media(min-width: 641px) {
  .photo-frame:first-child { transform: translateY(-10vw) }
  .photo-frame:last-child { transform: translateY(10vw) }
}
@media(max-width: 640px) {
  .photos {
    flex-direction: column;
  }
  .photo {
    width: 60vw;
    height: 37.08vw;
    background-color: #eee;
  }
  .photo-frame {
    margin: 7.5vw 0;
  }
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="wrapper">
  <section class="photos">
    <div class="photo-frame">
      <div class="photo"></div>
    </div>
    <div class="photo-frame">
      <div class="photo"></div>
    </div>
    <div class="photo-frame">
      <div class="photo"></div>
    </div>
  </section>
</div>
&#13;
&#13;
&#13;

playground

::}&lt;(((*&gt; ::)