【问题标题】:Fullscreen infinite scrolling background全屏无限滚动背景
【发布时间】:2017-09-30 09:22:12
【问题描述】:

我正在尝试实现全屏无限滚动背景效果,它必须在视口的整个高度和宽度上延伸。

这是demo

我尝试过的解决方案是采用具有100vh100vw 视口的包装元素,然后在其中放置2 个divs,100% 的高度,具有相同的背景-图片和background-size: cover 属性。我使用的图片尺寸是:1,920px × 808px

然后我在包装元素上应用了以下动画:

@keyframes infiniteScrollBg {
  0% {
    transform: translateY(0%);
  }
  100%{
    transform: translateY(-100%);
  }
}

但问题是在某些视口大小上,图像不能正确重复(因为background-size: cover 属性):

.

这是我尝试过的完整代码:

<div class="animated-scene">
    <div class="animated-scene__frame animated-scene__frame-1"></div>
    <div class="animated-scene__frame animated-scene__frame-2"></div>
</div>

还有css:

.animated-scene {
    width: 100vw;
    height: 100vh;
    position: fixed;
    min-height: 400px;
    animation: infiniteScrollBg 50s linear infinite;
 }

 .animated-scene__frame {
     width: 100%;
     height: 100%;
     background-size: cover;
     background-color: #4277a3;
     background-image: url('https://andreivictor.ro/codepen/fullscreen-infinite-scroll-bg/fullscreen-bg');
}

您对如何实现此效果有任何想法吗?

感谢您的帮助。

【问题讨论】:

    标签: css css-animations translate-animation background-size


    【解决方案1】:

    我使用图像元素只是为了使用它的自动高度。

    然后我在伪类上使用背景,它可以根据需要重复多次

    我设置了 2 个不同纵横比的不同容器,以便更轻松地在不同屏幕上查看结果

    .container {
      border: solid 1px black;
      overflow: hidden;
      position: absolute;
    }
    
    #ctn1 {
      width: 300px;
      height: 150px;
    }
    
    #ctn2 {
      width: 200px;
      height: 350px;
      left: 320px;
    }
    
    .inner {
      width: 100%;
      position: relative;
      animation: scroll 5s infinite linear;
    }
    
    .inner:after {
      content: "";
      height: 500%;
      width: 100%;
      position: absolute;
    
      background-image: url(https://i.stack.imgur.com/FlK9o.jpg);
      background-size: 100% 20%;
    }
    
    .img {
      width: 100%;
    }
    
    
    @keyframes scroll {
      from {transform: translateY(-100%);}
        to {transform: translateY(-200%);}
    
    }
    <div class="container" id="ctn1">
        <div class="inner">
            <img class="img" src="https://i.stack.imgur.com/FlK9o.jpg">
        </div>
    </div>
    <div class="container" id="ctn2">
        <div class="inner">
            <img class="img" src="https://i.stack.imgur.com/FlK9o.jpg">
        </div>
    </div>

    一个更好的解决方案,使用媒体查询来改变图像的使用方式。

    请注意,当图像和窗口的纵横比都未知时,需要使用 background-size:cover。由于您知道图像的纵横比,因此您可以使用基于它的媒体查询来控制显示。

    现在,当需要时,图像不会适应容器的宽度,而是适应容器的高度

    @media screen and (max-aspect-ratio: 4/3) {
        .inner {
            height: 100%;
            width: auto !important;
        }
        .img {
           height: 100%;
           width: auto !important;
        }
    }
    
    
    .container {
      border: solid 1px black;
      display: inline-block;
      overflow: hidden;
    }
    
    #ctn1 {
      width: 300px;
      height: 150px;
    }
    
    #ctn2 {
      width: 200px;
      height: 350px;
    }
    
    .inner {
      width: 100%;
      position: relative;
      animation: scroll 5s infinite linear;
      display: inline-block;
    }
    
    
    .inner:after {
      content: "";
      height: 500%;
      width: 100%;
      left: 0px;
      position: absolute;
      background-image: url(https://i.stack.imgur.com/FlK9o.jpg);
      background-size: 100% 20%;
    }
    
    .img {
      width: 100%;
    }
    
    
    @keyframes scroll {
      from {transform: translateY(-100%);}
        to {transform: translateY(-200%);}
    
    }
    <div class="container" id="ctn1">
        <div class="inner">
            <img class="img" src="https://i.stack.imgur.com/FlK9o.jpg">
        </div>
    </div>
    <div class="container" id="ctn2">
        <div class="inner">
            <img class="img" src="https://i.stack.imgur.com/FlK9o.jpg">
        </div>
    </div>

    【讨论】:

    • 好主意!我已经在我的示例中实现了它并且它有效:codepen.io/andreivictor/pen/xdPwXr.
    • 玩你的codepen,我注意到在极端的纵向比例下,屏幕底部没有被覆盖。您应该将伪元素的高度更改为 500% 以上(比如说 1000%),然后背景大小将是 100% 10%
    • 是的,我已经看到了这个缺点:imgur.com/a/PfKCU。此外,1000% 的高度会使元素太大,动画可能会有点不稳定。我认为一个完整的解决方案是根据屏幕尺寸使用一些不同的图像(用于移动设备、平板电脑和小型台式机,另一个用于全高清屏幕)。但是,这是最好的答案,我会将其标记为已接受。
    • 很高兴它有帮助!但我不认为这个高度会使动画起伏不定。您还可以在媒体查询中切换到 width: 50%(或更少)
    • 我添加了一个更好的解决方案。希望你喜欢!
    【解决方案2】:

    对于滚动背景,我使用背景位置而不是使用附加元素,并使用变换 css 属性对其进行动画处理。

    你为什么会问?

    1. 图案将由浏览器无缝拼接
    2. 更简洁的 HTML 代码。我们只需要一个元素就可以做到这一点。

    执行此方法的唯一 const 是您需要知道您正在使用的图像的尺寸。

    例子:

    /*
      specify the scroll x (or y) with the width (or height) of the images
      In this case, the image dimension is :
      width: 1920px;
      height: 808px;
    */
    
    @keyframes bgScroll {
      0% {
        background-position : 0px 0px
      }
      100% {
        background-position : 0px -808px
      }
    }
    
    .scrollingBG {
      display:block;
      width:100vw;
      height:100vh;
      background-image:url("https://andreivictor.ro/codepen/fullscreen-infinite-scroll-bg/fullscreen-bg.jpg");
      animation: bgScroll 20s linear infinite;
    }
    &lt;div class='scrollingBG'&gt;&lt;/div&gt;

    【讨论】:

    • 谢谢,您的解决方案非常适合这个问题。
    • 动画background-position 性能不是很好,因为它会导致大量重绘。最好改用翻译。
    【解决方案3】:

    问题在于纵横比。您将纵横比设置为视图窗口,而不是图像大小。因此,您的图像最终会在视图窗口方面被截断。

    我在你的 codepen 中通过将 .animated-scene__frame 更改为:

     .animated-scene__frame {
        width: 100%;
        height:200vh; //easy way - increase height in animated div to prevent image cutoff. Ideally should be done through javascript using like a 3x multiple of the height of the image. Then just rely on background-repeat during the animation :)
        background-size:contain;
        background-color: #4277a3;
        background-image: url('https://andreivictor.ro/codepen/fullscreen-infinite-scroll-bg/fullscreen-bg-slide1.jpg');
     }
    

    【讨论】:

      【解决方案4】:

      我建议将图片扩展 3 倍,其中:

      @keyframes infiniteScrollBg {
       0% {
         transform: translateY(0%);
       }
       100%{
         transform: translateY(-66.66%);
       }
      }
      

      使用一些图像编辑器并创建一个具有相同图案的大图像,看看我制作的这个网站site,在那里你会发现一些无限的背景图案

      【讨论】:

      • 在您的示例中,“移动”元素具有固定尺寸:高度 - 396 像素和宽度 - 5758 像素....它。
      【解决方案5】:

      您必须使用 background-position 属性。 这是固定示例http://codepen.io/azamat7g/pen/BRwRVV

      完整代码:

      @keyframes infiniteScrollBg {
        0% {
          transform: translateY(0%);
        }
        100%{
          transform: translateY(-100%);
        }
      }
      
      .animated-scene {
        width: 100vw;
        height: 100vh;
        position: fixed;
        min-height: 400px;
        animation: infiniteScrollBg 50s linear infinite;
      }
      
      .animated-scene__frame {
        width: 100%;
        height: 100%;
        background-size: cover;
        background-position: bottom left;
        background-color: #4277a3;
        background-image: url('https://andreivictor.ro/codepen/fullscreen-infinite-scroll-bg/fullscreen-bg-slide1.jpg');
      }
      
      .bottom{
        background-position: top left;
      }
      <div class="animated-scene">
        <div class="animated-scene__frame animated-scene__frame-1"></div>
        <div class="animated-scene__frame animated-scene__frame-2 bottom"></div>
      </div>

      【讨论】:

      • 它不循环...在动画结束时图像会跳转,因为背景位置不同。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-24
      • 2015-04-28
      相关资源
      最近更新 更多