带有动画的事件时间线
Posted
技术标签:
【中文标题】带有动画的事件时间线【英文标题】:Event timeline with animation 【发布时间】:2021-12-31 21:34:28 【问题描述】:我正在尝试构建的是带有一些动画的垂直时间轴组件。我正在尝试的动画是它从第一个圆圈开始,无论哪个项目的状态为真,垂直线将从上到下绘制,同时无论哪个步骤完成,当线穿过它时,将从圆形变为完成复选标记。
如何实现上面的动画,到目前为止我已经尝试过但不知道如何实现上面的。
我想达到什么目的this
sandbox
感谢任何帮助。
【问题讨论】:
【参考方案1】:我已经修改了您的沙盒以使其正常工作: https://codesandbox.io/s/animable-timeline-reactjs-tiofz
对于动画,我使用了以下 CSS:
div
height: 200px;
width: 10px;
.green-progress
background: linear-gradient(0, #00a36c, #00a36c) no-repeat, #ccc;
background-size: 100% 0;
animation: progressAnim 3s linear infinite forwards;
@keyframes progressAnim
0%
background-size: 100% 0;
100%
background-size: 100% 100%;
<div class="green-progress"></div>
为了使实际时间线动画化,我们将从第一个条目中删除垂直条,并且只有选中的圆圈。从第二个条目开始,我们将有一个垂直条和选中的圆圈。为了使它们保持一致,它们已向上移动。为了显示进度,该条将填充,然后将检查圆圈。
将App
转换为有状态组件,以便我们可以维护动画状态。
在构造函数中,为每个条目添加了id
、startAnim
和checked
状态。在这里,我们将设置startAnim
标志以在相应的TimelineConnector 上启动动画。 checked
用于控制对圆圈的勾选。
在TimelineConnector
中,如果this.props.startAnim
为真,则将类设置为绿色进度。还添加了onAnimationEnd
处理程序作为() => this.props.onAnimDone(this.props.id)
。这告诉 App 组件动画是在这个组件上用id
完成的。
在TimelineDot
中使用props.event.checked
设置检查状态。
在 App 中添加了一个生命周期钩子 componentDidMount
,当所有组件都添加到实际 DOM 时,它将被调用。在钩子中,您选中第一个圆圈并在第一个 TimelineConnector 上启动动画。
当 TimelineConnector 完成动画后,它会在 App 中调用 startNextAnim
。在该方法中,您首先完成最后一个条目的复选标记。如果条目有status:true
,则开始下一个动画。
【讨论】:
感谢您提供详细信息,我会仔细检查,如果有任何问题会更新,感谢您的帮助和信息 :) @onkar,对此有任何帮助***.com/questions/70157795/…【参考方案2】:你可以试试这个
/* timeline css */
@keyframes fill-color
0%
height: 0;
100%
height: 100%;
@keyframes fill-color1
0%
height: 0;
100%
height: 50%;
@keyframes scaleup
0%
transform: scale(0);
100%
transform: scale(1);
@keyframes fade
0%
color: rgba(black, 0.4);
100%
color: rgba(black, 1);
body
margin: 0;
padding: 0;
.timeline
padding: 0;
list-style: none;
margin: 32px;
overflow: hidden;
position: relative;
.details
margin-left: 48px;
border-bottom: 1px solid #f2f2f2;
min-height: 85px;
display: flex;
justify-content: center;
flex-direction: column;
.list,
.list-content
position: relative;
width: 100%;
.list-content::before,
.list-content::after
content: "";
display: block;
position: absolute;
left: 0;
transition: 0.2s all linear;
width: 0.714rem;
height: 0.714rem;
border-radius: 50%;
background-color: gray;
top: 50%;
z-index: 3;
margin-left: 0.35rem;
margin-top: rem(-8px);
.list-content::after
z-index: 2;
.list
position: relative;
width: 100%;
.list.active .list-content:before
transform: scale(0);
width: 17px;
height: 17px;
border: 2px solid white;
background-color: red;
background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/2/27/White_check.svg/2048px-White_check.svg.png");
background-position: center;
background-repeat: no-repeat;
background-size: 9px 7px;
margin-left: 0;
margin-top: -8px;
animation: scaleup 0.4s forwards;
.list:before,
.list:after
content: "";
display: block;
position: absolute;
left: 0;
transition: 0.2s all linear;
width: 0.214rem;
margin-left: 0.6rem;
.list:before
background: #f2f2f2;
height: 100%;
.list:after
background: red;
height: 0;
z-index: 1;
.list:before
top: -50%;
.list.active:after
top: 0;
animation: fill-color 0.4s forwards;
.list:last-child:after
display: none;
.list:last-child.active:after
display: block;
bottom: 50%;
animation: fill-color1 0.4s forwards;
.list:last-child .details
border-bottom: none;
.list:first-child:before
display: none;
.list:first-child.active:after
animation: fill-color1 0.4s forwards;
top: 50%;
.list:first-child.active:after
animation-delay: 1s;
.list:first-child.active .list-content:before
animation-delay: 0.5s;
.list:nth-child(2).active:after
animation-delay: 2s;
.list:nth-child(2).active .list-content:before
animation-delay: 2s;
.list:nth-child(3).active:after
animation-delay: 3s;
.list:nth-child(3).active .list-content:before
animation-delay: 3s;
.list:nth-child(4).active:after
animation-delay: 4s;
.list:nth-child(4).active .list-content:before
animation-delay: 4.15s;
<body>
<ul class="timeline">
<li class="list active">
<div class="list-content">
<div class="details">
<h4 class="status-title">Step 1</h4>
</div>
</div>
</li>
<li class="list active">
<div class="list-content">
<div class="details">
<h4 class="status-title">Step 2</h4>
</div>
</div>
</li>
<li class="list active">
<div class="list-content">
<div class="details">
<h4 class="status-title">Step 3</h4>
</div>
</div>
</li>
<li class="list active">
<div class="list-content">
<div class="details">
<h4 class="status-title">Step 4</h4>
</div>
</div>
</li>
</ul>
</body>
您也可以查看Sandbox
在这里,我在所有 li
元素中添加了 active
类,但如果您想激活两个步骤,那么只应用前两个 li(即该类是有条件的)
【讨论】:
【参考方案3】:可以为背景设置动画。请检查下面的示例
.bg
min-height: 300px;
width: 10px;
background: linear-gradient(0, red, red) no-repeat;
background-size: 100% 0;
animation: gradient 15s ease infinite;
@keyframes gradient
0%
background-size: 100% 0;
100%
background-size: 100% 100%;
<div class="bg"></div>
您的 TimelineConnector 可以使用包含该 CSS 类的内容进行更新。
【讨论】:
谢谢,在这里我尝试过使线条动画化,但问题是我不知道如何像 gif 中所示那样逐一制作动画,因为根据数据只完成了三个,所以如何应该画一条线,直到完成我无法继续前进的步骤 当然,您可以为动画添加一个附加参数,作为从您的 React 脚本定义的 CSS 变量,其中包含项目数 * 超时,类似于:animation: gradient 15s ease infinite var(--timeout ); 要在元素范围内定义 CSS 变量,您可以使用这样的方法: element.style.setProperty('--timeout', '0.5s'); 对不起,可能是新手,如果你能帮忙,你能像 Gif 一样分享你能够解决的代码框 它可以通过项目和一组不同的超时来循环。示例:codepen.io/alekskorovin/pen/ExvJOrz以上是关于带有动画的事件时间线的主要内容,如果未能解决你的问题,请参考以下文章