如何构建“滑入”的 CSS 动画,在完成滑动后显示文本/div?

Posted

技术标签:

【中文标题】如何构建“滑入”的 CSS 动画,在完成滑动后显示文本/div?【英文标题】:How to build a CSS animation that "slides in", revealing a text/div after it finishes sliding? 【发布时间】:2020-07-08 18:02:26 【问题描述】:

我正在尝试从此处的网站模仿 CSS 动画:https://stanographer.com/

我要复制网站的方式:

首先显示一个向右滑动的全屏黑色 div

“加载”文本后面的黑色背景(div 标签)(如“嗨,我是 Stanley Sakai”),从左到右扩展

在黑色背景 div 上“加载”文本,从左向右扩展。

现在您可能会问,“为什么不检查页面,查看 div 和文本上的类,然后检查网络选项卡中的 CSS 表?”我已经试过了。 CSS看起来很奇怪。我的朋友说它是由 SASS 预处理的,不管那是什么意思。无论如何,我无法破译密码。

我访问过几个不同的 *** 页面 (here's one) 和十几个不同的 Google 页面。我了解了如何使用关键帧,但我还没有弄清楚如何在 Stanographer.com 上重新创建效果。我拥有该网站的朋友也提供了this 示例,但我不知道如何将其应用于单个 div。他说了一些关于使用 z-index 的内容,但我就是没看到。

我知道要让页面以全黑屏开始然后滑出,我必须使用 javascript 触发类更改。我有:

let blackStuff = document.getElementById("blackness");

window.addEventListener("load", () => 
    console.log("loaded");
    blackStuff.setAttribute("class", "black-box-out");
  ,
  false
);
.black-box 
  position: fixed;
  float: left;
  top: 0;
  width: 100%;
  height: 100%;
  bottom: 0;
  background-color: #000;
  z-index: 999999;
  -webkit-animation: powerslide 0.5s forwards;
  -webkit-animation-delay: 2s;
  animation: powerslide 0.5s forwards;
  animation-delay: 2s;


@-webkit-keyframes powerslide 
  100% 
    left: 0;
  


@keyframes powerslide 
  100% 
    left: 0;
  


.black-box-out 
  margin-left: 100%;
  animation: slide 0.5s forwards;
  -webkit-transition: slide 0.5s forwards;
  transition: slide 0.5s forwards;
<div id="blackness" class="black-box"></div>

但这只会使“黑色” div 在页面加载时立即消失。我想让它滑出来。显然,我不明白如何使用 CSS 动画。

如果您有兴趣了解更多无效的内容,请继续阅读。否则,您可以跳过此部分:它只显示我失败的试验。

我已经学会了如何让 CSS 动画从 0 开始水平扩展:

.wrapper 
  position: relative;
  overflow: hidden;
  width: 500px;
  height: 50px;
  border: 1px solid black;


.slide-custom 
  width: 500px;
  height: 50px;
  background: cyan;
  position: relative;
  -webkit-animation: slideIn 2s forwards;
  animation: slideIn 2s forwards;



/* moz and webkit keyframes excluded for space */

@keyframes slideIn 
  0% 
    transform: scaleX(0);
  
  100% 
    transform: scaleX(1);
  
<div class="wrapper slide-custom">
  <h1 class="slide-custom">
    <span>MEET ROLY POLY.</span>
    <!-- expands horizontally from 0 width to 100% width -->
  </h1>
</div>

我已经学会了让文本从左侧“滑入”,尽管当我希望它以 0% 宽度开始时,它以 100% 宽度开始:

/* CSS */

.test-slide 
  animation-duration: 3s;
  animation-name: testSlide;


@keyframes testSlide 
  from 
    margin-left: 0%;
    width: 50%;
  
  to 
    margin-left: 100%;
    width: 100%;
  
<div class="test-slide">
  <h1><span>ABOUT.</span></h1>
  <!-- will slide in from the left -->
</div>

还有更多——不幸的是,没有一个模仿我要复制的网站。

【问题讨论】:

我建议下次使用Ctrl+M 发布可运行的sn-ps,以便人们可以轻松运行它。此外,使用 gif 而不是链接到特定网页会更好,因为将来可能无法访问。就我而言,您链接的网站需要很长时间才能运行我的浏览器(如果您使用了 gif,这是可以避免的);这甚至会阻止回答者尝试回答。 【参考方案1】:

您可以使用 CSS3 过渡或 CSS3 动画来滑动元素。

浏览器支持:http://caniuse.com/

我做了两个简单的例子来说明我的意思。

CSS 过渡(悬停时)

演示一

相关代码

.wrapper:hover #slide 
    transition: 1s;
    left: 0;

在这种情况下,我只是从左侧转换位置:-100px;为 0; 1s。期间。也可以使用 transform: translate();

移动元素

CSS 动画

演示二

#slide 
    position: absolute;
    left: -100px;
    width: 100px;
    height: 100px;
    background: blue;
    -webkit-animation: slide 0.5s forwards;
    -webkit-animation-delay: 2s;
    animation: slide 0.5s forwards;
    animation-delay: 2s;


@-webkit-keyframes slide 
    100%  left: 0; 


@keyframes slide 
    100%  left: 0; 

原理同上(Demo One),但是动画2s后自动开始,这里我设置了animation-fill-mode为forwards,会保持结束状态,保持动画时div可见结束。

就像我说的,两个简单的例子向您展示如何做到这一点。

编辑:有关 CSS 动画和过渡的详细信息,请参阅:

动画

https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations

过渡

https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions

希望这会有所帮助。

【讨论】:

是的,我看到了。创建一个可以滑入并位于屏幕左侧的框。如果我删除 position: absolute; 它位于包含 标记中并且不会移动。通过添加@-webkit-keyframes slide 0% left: -100px; 100% left: 0px; 进一步尝试自定义不会做任何事情。我读了那页,伙计。 你能解释一下你到底想做什么【参考方案2】:

这里有一些 CSS3 动画,当 .entrance-animation 获得 .active 类时触发该动画。

当项目进入视图时,您需要一个观察者来观察,当项目可见时,您将 .active 类添加到它。

希望对你有帮助!

setTimeout(() =>

  let animate = document.querySelectorAll('.entrance-animation');
  
  animate.forEach(item => item.classList.add('active'));

,1000);
.entrance-animation

  position: relative;
  color: blueviolet;
  white-space: nowrap;
  font-size: 24px;
  width: 0;
  overflow: hidden;
  transition: width 0.5s ease;

.entrance-animation::before

  content: '';
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: 100%;
  background-color: black;
  z-index: 10;
  transition: width 0.5s ease;
  transition-delay: 0.5s;

.entrance-animation.active

  width: 100%;

.entrance-animation.active::before

  width: 0%;
<p class="entrance-animation">
  Hello
</p>
<p class = "entrance-animation">
  Here we are
</p>

【讨论】:

使用宽度制作动画导致动画效果不如预期。前几帧将框显示为垂直的长框(不应该是这种情况)。【参考方案3】:

说明

有多种方法可以实现您真正想要的。我没有选择动画width。动画的前几帧将不如预期。

因此,我们可以使用clip-pathclip-path 基本上做的是掩蔽。您可以“裁剪”一个 div,使其只有一部分可见。我们将使用clip-path::before::after 伪元素(都可以)来创建这个动画。我们需要做的:

创建伪元素并定位它,使其覆盖(位于顶部)整个可动画元素 (position: absolute) 将伪元素的背景设置为黑色 使用clip-path,屏蔽动画元素以不显示元素的任何部分(这也会导致伪元素不显示,因为它是元素的一部分)。剪辑的方向很重要。这里的方向是从右侧到左侧。 使用animation@keyframes,取消屏蔽之前屏蔽的div。这将从左侧到右侧慢慢地显示它(因为最初,我们从右到左屏蔽它;在取消屏蔽时,会发生相反的方向) 取消屏蔽元素后,伪元素将位于我们要显示的文本之上 片刻之后,将伪元素(不是整个元素)从右向左屏蔽,再次使用clip-path,使文本看起来缓慢显示李>

有效!但是,我建议阅读有关clip-path 的内容。此外,我非常喜欢使用的一个非常方便的剪辑路径 CSS 生成器是this(如果你想从右到左剪辑,你应该从右到左拖动点)。我还强烈推荐阅读 CSS positioning(优秀 CSS 动画的主要内容)。你不必使用z-index: 9999;您通常希望跟踪您使用的z-index


解决方案

这是使用所述方法的有效解决方案。尝试运行它。

* 
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  font-family: Helvetica;


body,
html 
  width: 100%;
  height: 100%;


#wrapper 
  background: #555555;
  width: 100%;
  height: 100%;
  color: white;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;


#wrapper * 
  margin: 5px;


.heading 
  font-size: 3em;
  padding: 10px 5px;


.caption 
  font-size: 1em;
  padding: 5px;
  font-family: Courier;


.animatable 
  position: relative;
  clip-path: polygon(0 0, 0 0, 0 100%, 0% 100%);
  animation: .75s cubic-bezier(1,-0.01,.12,.8) 1s 1 reveal forwards;


.animatable::after 
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #20262b;
  padding: inherit;
  animation: .75s cubic-bezier(1,-0.01,.12,.8) 1.75s 1 hideBlack forwards;


@keyframes reveal 
  from  clip-path: polygon(0 0, 0 0, 0 100%, 0% 100%); 
  to  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); 


@keyframes hideBlack 
  from  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); 
  to  clip-path: polygon(100% 0, 100% 0, 100% 100%, 100% 100%); 
<div id="wrapper">
  <div class="heading animatable">Hi, I am Richard!</div>
  <div class="caption animatable">I am a person.</div>
</div>

虽然您想要的简单动画可以仅使用 CSS 来创建,但我仍然建议您阅读有关如何使用 JavaScript 制作动画以及它在制作动画时拥有的各种库。这是因为一旦有许多动画和过渡正在进行,就很难跟踪动画(尤其是当您希望动画在另一个动画结束后开始时)。一个好的库是anime.js(在确定一个之前一定要探索更多选项)。此外,请注意动画如何仅在您提供的网站中向下滚动时出现?这仅适用于 JS(其中一种方法是使用大多数浏览器提供的IntersectionObserver API)。

【讨论】:

以上是关于如何构建“滑入”的 CSS 动画,在完成滑动后显示文本/div?的主要内容,如果未能解决你的问题,请参考以下文章

如何将QML查看器自身滑入屏幕

使用css或js关闭时如何向右滑动bootstrap 4模态对话框

CSS滑入和滑出动画溢出问题

vue 路由切换动画(滑入,滑出效果)

jQuery - 02. 样式表属性操作/类操作动画显示隐藏滑入淡入停止动画节点操作添加对象清空节点

如何使css动画与离子中的手指滑动同步?