>我可以根据需要通过媒体查询交换图像集
>可以动画背景以产生幻灯片效果
我有背景大小:封面和背景剪辑:内容框,这些正确地将图像保持在容器的所需区域内,确保正确地剪掉多余的部分.
第一个问题是在CSS动画期间,当一个图像转换到另一个图像时,新图像会在该关键帧的时间过程中调整大小.我想要的是将下一个图像转换为(已经适当的大小),而不会看到它调整大小.
实际上,我甚至不确定为什么首先会出现交叉淡入淡出可视化,因为我没有指示这样做(也许是内置的-webkit-动画?).我原以为你只会看到从一张图片到另一张图片的即时更改.我实际上喜欢交叉淡入淡出,但不知道它来自哪里让我觉得它与调整大小问题有关.
第二个问题是在幻灯片放映的第一次迭代(仅)期间,存在图像的闪烁,并且简要地示出了容器元素的白色背景颜色.因为这只发生在第一次迭代时,我认为这可能是图像的初始下载时间的问题,这就是为什么它在后续迭代中消失的原因.但是,当我在幻灯片放映开始之前添加一些JavaScript来预加载图像并发现同样的问题时,事实证明并非如此.此外,一旦你运行该节目,你有缓存中的图像和刷新页面(这将只是从缓存中获取图像,是的,我通过从我自己的测试服务器获取文件来测试它,所以他们将正确缓存)闪烁再次发生.
我已经看过一些关于使用preserve3d等来消除闪烁的各种CSS属性设置的帖子,但这些都没有帮助.
我在Windows 10上使用Chrome 62.0.3202.94桌面.
#outerFrame { background-color: #22130c; Box-shadow: inset 0 1px 1px 1px hsla(0,0%,100%,.2),inset 0 -2px 1px hsla(0,.4),0 5px 50px hsla(0,.25),0 20px 20px -15px hsla(0,0 30px 20px -15px hsla(0,.15),0 40px 20px -15px hsla(0,.1); padding: 1.5em; overflow: auto; float: left; margin: 0 1em 1em 0; } #innerFrame { background-color: #fff5e5; Box-shadow: 0 2px 1px hsla(0,0 -1px 1px 1px hsla(0,inset 0 2px 3px 1px hsla(0,inset 0 4px 3px 1px hsla(0,inset 0 6px 3px 1px hsla(0,.1); padding: 1.5em; } /* This is the relevant style: */ #innermostFrame { padding: .75em; background-color: #fff; Box-shadow: 0 -1px 0 2px hsla(0,.03); background-position: 50% 50%; background-repeat: no-repeat; background-size:cover; background-clip: content-Box; animation: cycle 8s ease-in-out infinite; width: 30vw; height:40vh; min-width: 200px; max-width: 900px; } @keyframes cycle { 0% { background-image: url("https://picsum.photos/200/300/?random"); } 25% { background-image: url("https://picsum.photos/640/480/?random"); } 50% { background-image: url("https://picsum.photos/1900/1200/?random"); } 75% { background-image: url("https://picsum.photos/480/200/?random"); } 100% { background-image: url("https://picsum.photos/600/300/?random"); } }
<div id="outerFrame"> <div id="innerFrame"> <div id="innermostFrame"></div> </div> </div>
我意识到我可以使用其他各种技术(即JavaScript,堆叠< img>元素和管理不透明等)来解决这些问题,但我真的想了解导致这两个问题的原因.
解决方法
发生这种情况是因为浏览器尝试在关键帧之间设置动画.如果我们看看你的@keyframes周期,我们会看到你每25%创建一个关键帧.这意味着浏览器的动画范围为0%到25%.它的动画是什么?背景改变了.它将如何制作动画?交叉淡入淡出.此外,背景的大小再次覆盖div(使用的图片格式不同 – 如果使用相同的格式 – 这可能不会发生).
@keyframes cycle { 0% { background-image: url("https://picsum.photos/200/300/?random"); } 25% { background-image: url("https://picsum.photos/640/480/?random"); } 50% { background-image: url("https://picsum.photos/1900/1200/?random"); } 75% { background-image: url("https://picsum.photos/480/200/?random"); } 100% { background-image: url("https://picsum.photos/600/300/?random"); } }
解决方案A(无交叉淡入淡出和白色背景)
您可以通过让动画几乎瞬间发生来摆脱调整大小:
0% { background-image: url("https://picsum.photos/200/300/?random"); } 24.99% { background-image: url("https://picsum.photos/200/300/?random"); } 25% { background-image: url("https://picsum.photos/640/480/?random"); }
关键帧0%中的背景在关键帧24.99%处是相同的,因此它不具有动画效果.然后它变化为25%(这看起来像一个即时更改)请参阅下面的工作片段:
#outerFrame { background-color: #22130c; Box-shadow: inset 0 1px 1px 1px hsla(0,.1); padding: 1.5em; overflow: auto; float: left; margin: 0 1em 1em 0; } #innerFrame { position: relative; background-color: #fff5e5; Box-shadow: 0 2px 1px hsla(0,.1); padding: 1.5em; } /* This is the relevant style: */ #innermostFrame{ padding: .75em; background-color: #fff; Box-shadow: 0 -1px 0 2px hsla(0,.03); background-position: 50% 50%; background-repeat: no-repeat; background-size:cover; background-clip: content-Box; animation: cycle 8s ease-in-out infinite; width: 30vw; height:40vh; min-width: 200px; max-width: 900px; } @keyframes cycle { 0% { background-image: url("https://picsum.photos/200/300/?random"); } 24.99% { background-image: url("https://picsum.photos/200/300/?random"); } 25% { background-image: url("https://picsum.photos/640/480/?random"); } 49.99% { background-image: url("https://picsum.photos/640/480/?random"); } 50% { background-image: url("https://picsum.photos/1900/1200/?random"); } 74.99% { background-image: url("https://picsum.photos/1900/1200/?random"); } 75% { background-image: url("https://picsum.photos/480/200/?random"); } 99.99% { background-image: url("https://picsum.photos/480/200/?random"); } 100% { background-image: url("https://picsum.photos/200/300/?random"); } }
<div id="outerFrame"> <div id="innerFrame"> <div id="innermostFrame"></div> </div> </div>
请注意!最后一个关键帧(100%)应该设置为与第一个关键帧(0%)相同的值,因为我们希望循环从它停止的地方开始.实际上,这意味着在此示例中您只有4个不同的背景图像(如果您想要5个 – 取代20%的步长).
我们通过调整大小背景来解决问题.作为副作用,我们还“修复”了交叉渐变.真正的缺点是我们在动画第一次播放时仍然具有白色背景.
2.白色背景
我认为出现白色背景是因为需要首先加载图像.它们仅在动画运行时加载.这就是为什么第一次运行低谷有白色背景的原因.
解决方案B(交叉淡入淡出,无白色背景)
我们可以使用辅助div来获得交叉淡化效果.但我们必须在keframe中设置不透明度.我们可以在显示另一个div的同时在关键帧中设置背景图像 – 因此它有更多的时间加载并且不会出现白色背景.请参阅下面的代码段:
#outerFrame { background-color: #22130c; Box-shadow: inset 0 1px 1px 1px hsla(0,.1); padding: 1.5em; } /* This is the relevant style: */ #innermostFrame,#innermostFrame2{ padding: .75em; background-color: #fff; Box-shadow: 0 -1px 0 2px hsla(0,.03); background-position: 50% 50%; background-repeat: no-repeat; background-size:cover; background-clip: content-Box; animation: cycle 8s ease-in-out infinite; width: 30vw; height:40vh; min-width: 200px; max-width: 900px; } #innermostFrame2{ position: absolute; top: 1.5em; /* padding of innerFrame */ animation: cycle2 8s infinite; background-image: url("https://picsum.photos/200/300/?random"); } @keyframes cycle { 0% { background-image: url("https://picsum.photos/640/480/?random"); } 50% { background-image: url("https://picsum.photos/640/480/?random"); } 51% { background-image: url("https://picsum.photos/480/200/?random"); } 100% { background-image: url("https://picsum.photos/480/200/?random"); } } @keyframes cycle2 { 15% { opacity: 1;} 25% { opacity: 0; background-image: url("https://picsum.photos/200/300/?random"); } 26% { background-image: url("https://picsum.photos/1900/1200/?random");} 40% { opacity: 0;} 50% { opacity: 1;} 65% { opacity: 1;} 75% { opacity: 0; background-image: url("https://picsum.photos/1900/1200/?random");} 76% { background-image: url("https://picsum.photos/200/300/?random");} 90% { opacity: 0;} 100% { opacity: 1;} }
<div id="outerFrame"> <div id="innerFrame"> <div id="innermostFrame"></div> <div id="innermostFrame2"></div> </div> </div>
解决方案B解释:
这个想法是让背景图像在显示之前加载.因此,有2个div具有2个@keyframe动画,导致背景平滑交替.
#innermostFrame2获得与#innermostFrame相同的宽度和高度,并且绝对定位(直接位于其上方). #innermostFrame2显示并隐藏了25%的动画持续时间.以下是可见的:
25% 25% 25% 25% [ #innermostFrame2 - #innermostFrame - #innermostFrame2 - #innermostFrame ]
百分比:
已经为#innermostFrame2本身设置了背景图像 – 使其尽可能快地加载.在@keyframes cycle2中,不需要0%,因为背景已经设置并且可见.
我们希望图像显示25%的动画(4张图像).现在我决定在这个例子中10%的交叉淡入淡出看起来很好(8秒动画的10%是0.8秒).你可以做得更少或更多,因为这是一个品味的问题.这就是为什么动画的不透明度为1的15%和0的25%.在div不可见之后,我们立即将背景图像更改为26%,因此可以将其加载到CSS对象模型中.
#innermostFrame的背景现在可见(因为隐藏了#innermostFrame2).我们希望在动画持续时间的25%内显示此信息.因此,在50%时,我们希望#innermostFrame2再次以新背景显示.因为我决定交叉淡化动画持续时间的10%,我们从不透明度开始时为40%:0;.在#innermostFrame2完全显示(50%)之后,我们立即更改#innermostFrame的背景以加载它.这种情况发生在@keyframes周期的51%