Sco*_*cus 7 html css css3 css-animations
我有一个<div>我用作幻灯片放映图像的容器.将在容器中显示的图像具有不同的大小并应用为背景图像,而不是<img>容器内的元素,以便:
我有background-size:cover并且background-clip:content-box这些正确地将图像保持在容器的所需区域内,确保正确地剪掉多余的部分.
第一个问题是在CSS动画期间,当一个图像转换到另一个图像时,新图像会在该关键帧的时间过程中调整大小.我想要的是将下一个图像转换为(已经适当的大小),而不会看到它调整大小.
实际上,我甚至不确定为什么首先会出现交叉淡入淡出可视化,因为我没有指示这样做(也许是内置-webkit-动画?).我原以为你只会看到从一张图片到另一张图片的即时更改.我实际上喜欢交叉淡入淡出,但不知道它来自哪里让我觉得它与调整大小问题有关.
第二个问题是在幻灯片放映的第一次迭代期间(仅),图像闪烁,并且简要地示出了容器元素的白色背景颜色.因为这只发生在第一次迭代时,我认为这可能是图像初始下载时间的问题,这就是为什么它在后续迭代中消失的原因.但是,当我在幻灯片放映开始之前添加一些JavaScript来预加载图像并发现同样的问题时,事实证明并非如此.此外,一旦你运行节目,你有缓存中的图像和刷新页面(这将只是从你的缓存中获取图像,是的,我通过从我自己的测试服务器获取文件来测试它,所以他们将正确缓存)闪烁再次发生.
我已经看过一些关于使用各种CSS属性设置来消除闪烁的帖子preserve3d,但这些都没有帮助.
我在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,0%,0%,.4),
0 5px 50px hsla(0,0%,0%,.25),
0 20px 20px -15px hsla(0,0%,0%,.2),
0 30px 20px -15px hsla(0,0%,0%,.15),
0 40px 20px -15px hsla(0,0%,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%,100%,.2),
0 -1px 1px 1px hsla(0,0%,0%,.4),
inset 0 2px 3px 1px hsla(0,0%,0%,.2),
inset 0 4px 3px 1px hsla(0,0%,0%,.2),
inset 0 6px 3px 1px hsla(0,0%,0%,.1);
padding: 1.5em;
}
/* This is the relevant style: */
#innermostFrame {
padding: .75em;
background-color: #fff;
box-shadow: 0 -1px 0 2px hsla(0, 0%, 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"); }
}Run Code Online (Sandbox Code Playgroud)
<div id="outerFrame">
<div id="innerFrame">
<div id="innermostFrame"></div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
我意识到我可以使用其他各种技术(即JavaScript,堆叠<img>元素和管理opaccity等)来解决这些问题,但我真的想了解导致这两个问题的原因.
1.交叉淡入淡出:
发生这种情况是因为浏览器尝试在关键帧之间设置动画。如果我们查看您的 @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"); }
}
Run Code Online (Sandbox Code Playgroud)
解决方案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"); }
Run Code Online (Sandbox Code Playgroud)
关键帧 0% 中的背景与关键帧 24.99% 中的背景相同,因此它不会产生动画。然后它会以 25% 的速度变化(这看起来像是即时变化)请参阅下面的工作片段:
@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"); }
}
Run Code Online (Sandbox Code Playgroud)
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"); }
Run Code Online (Sandbox Code Playgroud)
注意!最后一个关键帧 (100%) 应设置为与第一个关键帧 (0%) 相同的值,因为我们希望循环从停止处开始。实际上,这意味着在此示例中您只有 4 个不同的背景图像(如果您想要 5 个 - 则采取 20% 的步骤)。
我们解决了调整背景大小的问题。作为副作用,我们还“修复”了交叉淡入淡出。真正的缺点是动画第一次播放时我们仍然有白色背景。
2.白色背景
我认为出现白色背景是因为需要先加载图像。它们仅在动画运行时加载。这就是为什么第一次运行时有白色背景。
解决方案 B(使用交叉淡入淡出且无白色背景)
我们可以使用辅助 div 来恢复交叉淡入淡出效果。但我们必须在keframes中设置不透明度。我们可以在显示另一个 div 的同时在关键帧中设置背景图像 - 这样它就有更多的时间来加载并且不会出现白色背景。请参阅下面的片段:
#outerFrame {
background-color: #22130c;
box-shadow: inset 0 1px 1px 1px hsla(0,0%,100%,.2),
inset 0 -2px 1px hsla(0,0%,0%,.4),
0 5px 50px hsla(0,0%,0%,.25),
0 20px 20px -15px hsla(0,0%,0%,.2),
0 30px 20px -15px hsla(0,0%,0%,.15),
0 40px 20px -15px hsla(0,0%,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,0%,100%,.2),
0 -1px 1px 1px hsla(0,0%,0%,.4),
inset 0 2px 3px 1px hsla(0,0%,0%,.2),
inset 0 4px 3px 1px hsla(0,0%,0%,.2),
inset 0 6px 3px 1px hsla(0,0%,0%,.1);
padding: 1.5em;
}
/* This is the relevant style: */
#innermostFrame{
padding: .75em;
background-color: #fff;
box-shadow: 0 -1px 0 2px hsla(0, 0%, 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"); }
}Run Code Online (Sandbox Code Playgroud)
<div id="outerFrame">
<div id="innerFrame">
<div id="innermostFrame"></div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
解决方案B解释道:
这个想法是让背景图像在显示之前加载。因此,有 2 个 div 和 2 个@keyframe动画,从而实现平滑交替的背景。
#innermostFrame2获得与绝对定位相同的宽度和高度#innermostFrame(正上方)。#innermostFrame2的显示和隐藏时间为动画持续时间的 25%。可见如下:
25% 25% 25% 25%
[ #innermostFrame2 - #innermostFrame - #innermostFrame2 - #innermostFrame ]
Run Code Online (Sandbox Code Playgroud)
百分比:
背景图像已为其#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% 开始opacity: 0;。#innermostFrame2完全显示(50%)后,我们立即更改#innermostFrame的背景以使其加载。这种情况发生在 51%@keyframes cycle
| 归档时间: |
|
| 查看次数: |
865 次 |
| 最近记录: |