如何用JavaScript更新背景位置值来实现CSS视差滚动?

new9mtju  于 4个月前  发布在  Java
关注(0)|答案(1)|浏览(74)

在CSS中,使用JavaScript,如何将不同的Y位置百分比分配给layered background images,以便它们随着页面滚动而更新?

<style>
  body {
    background-image: 
      url(img/bg-pattern-01.png),
      url(img/bg-pattern-02.png),
      url(img/bg-pattern-03.png);
    background-position:
      center 45%,
      center 50%,
      center 55%;
  }
</style>

字符串
所以在上面的例子中,百分比(45%,50%,55%)不是静态值,而是受页面垂直滚动位置的动态影响。可能是实际滚动百分比的混合或平均混合。

5jdjgkvh

5jdjgkvh1#

轻松视差滚动,相对于页面顶部和底部

我的问题得到了一个答案(我已经接受了),但是那个贡献者已经删除了他们的答案。这是一个很有帮助的答案,它展示了一种可行的方法。在看了这里的一些其他答案之后,我能够改进这些方法,并把我所设想的放在一起:
一个多层视差滚动背景,可以在任何窗口大小下可靠地显示,并且可以全部包含在HTML BODY元素中。(不需要花哨的DIV工作。)这个解决方案使用jQuery -不管你喜欢与否,它在这种情况下非常有用。
用于演示的图像资产:

Animation credit
注意事项:imgur目前不支持WebP,但如果使用WebP,文件大小可以大大减少-在我的测试中,WebP平均约为PNG和GIF静态背景大小的8%-对于那些担心视差背景图像计数的性能影响的人来说。导出为WebP时所有静态图像的总大小为193 KB。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Parallax Scroll</title>
  <link rel="stylesheet" href="css/styles.css">
  <style type="text/css">

    body{
      margin: 0;
      height: 150vh; /* ensure enough content to allow scrolling */
      background-repeat: 
        repeat-x,
        repeat-x,
        repeat, /* particle GIF */
        repeat-x,
        repeat-x,
        no-repeat; /* unscripted */
      background-size: 
        100vw,
        100vw,
        33vw, /* particle GIF */
        100vw,
        100vw,
        cover; /* unscripted */
      background-position: 
        center bottom, /* lay1:btm (nearest)  */
        center bottom, /* lay2:btm  */
        center top, /* particle GIF */
        center top, /* lay3:top  */
        center bottom, /* lay3:btm  */
        center center; /* lay4 (farthest, unscripted, covers page ) */
      background-image: 
        url(https://i.stack.imgur.com/DdMld.png),
        url(https://i.stack.imgur.com/6Z2KU.png),
        url(https://i.stack.imgur.com/p7RgF.gif),
        url(https://i.stack.imgur.com/wwgc9.png),
        url(https://i.stack.imgur.com/L2XPa.png),
        url(https://i.stack.imgur.com/0p29i.gif);
      background-blend-mode:
        lighten, /* gives the foreground crystals a subtle bright transparent effect against the darker ones on lay2 */
        normal, /* lay2 darker (more purple) crystals - 'normal' blending is already perfect here */
        lighten, /* particle FX layer must use lighten (its background is black, no alpha) */
        normal, /* 'multiply' would be alright, but in small browser windows overlap occurs with layer below */
        multiply, /* since the bottom layer is very bright, multiply results in a subtle color change when scrolled */
        normal /* always 'normal' for the lowest layer in the stack */
    }

  </style>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
</head>
<body>

<script type="text/javascript">
// adds scrollBottom function | thanks: https://stackoverflow.com/a/30127031
$.fn.scrollBottom = function(scroll){
  if(typeof scroll === 'number'){
    window.scrollTo(0,$(document).height() - $(window).height() - scroll);
    return $(document).height() - $(window).height() - scroll;
  } else {
    return $(document).height() - $(window).height() - $(window).scrollTop();
  }
}

// defines calcView (main background scrolling function)
var calcView = function() {
  var scrollTop = Math.floor( $(document).scrollTop() ); // dist from elem's top to its topmost visible content
  var scrollBtm = Math.floor( $(document).scrollBottom() ); // relies on jQuery plugin, defined above

  // instructs layers to move away from (-amount px) the top or bottom of the page when scrolled
  // adjust the multiplier (* 0.x) to set the rate of movement relative to the scrolling
  // perceived distance will be closer with higher values (0.9), and farther with lower values (0.1)
  $('body').css({
    'background-position' : `
      center bottom -${(scrollBtm * 0.9)}px, /* lay1:btm nearest layer (bottom only in this example) */
      center bottom -${(scrollBtm * 0.6)}px, /* lay2:btm second nearest layer (bottom only in this example) */
      center top -${(scrollTop * 0.3)}px, /* particle GIF */
      center top -${(scrollTop * 0.2)}px, /* lay3:top farthest with scripted scrolling, lay3 scroll rate */
      center bottom -${(scrollBtm * 0.2)}px, /* lay3:btm farthest with scripted scrolling, lay3 scroll rate */
      center center /* farthest layer is unscripted, and always covers the page */
    `
  });

  // to verify scroll distances in the console
  //console.log(
  //  "scrollTop = " + scrollTop + "px from top" +
  //  "\nscrollBtm = " + scrollBtm + "px from bottom"
  //);
}

// binds function to multiple events | thanks: https://stackoverflow.com/a/2534107/2454914
$(document).ready(function(){ // once document is ready, listen for the following...
  $(document).on('scroll', calcView); // do calcView function if document is scrolled
  $(window).on('resize', calcView); // do calcView function if window is resized
});

</script>
</body>
</html>

字符串
关于这种方法,需要注意的主要一点是使用scrollTopscrollBottom函数来偏移页面顶部和底部的背景的简单性。任何给定的感知层(例如lay3)都可以同时具有 * 顶部 * 和 * 底部 * 图像。
我将 * 感知 * 层标记为lay1lay2等,以区别于CSS和脚本中的 * 有序 * 层。
一些background-blend-mode效果被包括在内,以说明可以实现的结果,对于那些谁喜欢geeking出与这类事情。
更多的细节即将到来,但首先请浏览冗长的注解代码片段。代码本身实际上并不很复杂。
运行完代码片段后,建议点击【整页】,即可看到完整的效果。

相关问题