带动画的事件时间线
我已经修改了您的沙箱以使其正常工作:https :
//codesandbox.io/s/animable-timeline-reactjs-tiofz
对于动画,我使用了以下 CSS:
为了动画实际时间线,我们将从第一个条目中删除垂直条,并且只会有一个选中的圆圈。从第二个条目开始,我们将有一个垂直条和选中的圆圈。为了使它们保持一致,它们已向上移动。为了显示进度,条形将填充,然后将检查圆圈。转换
App
为有状态组件,以便我们可以维护动画状态。在构造函数中,为每个条目增加id
,startAnim
以及checked
状态。在这里,我们将设置startAnim
标志以在相应的 TimelineConnector 上启动动画。和checked
用于控制对圆圈的勾选。TimelineConnector
如果this.props.startAnim
为 true,则在设置类中为 green-progress 。还添加了onAnimationEnd
处理程序作为{() => this.props.onAnimDone(this.props.id)}
. 这告诉 App 组件动画是在这个组件上完成的id
。在
TimelineDot
用于props.event.checked
设置检查状态。In App 添加了一个生命周期钩子
componentDidMount
,当所有组件被添加到实际 DOM 时,它会被调用。在钩子中,您选中第一个圆圈并在第一个 TimelineConnector 上开始动画。当 TimelineConnector 完成动画时,它会
startNextAnim
在应用程序中调用。在该方法中,您首先完成最后一个条目的复选标记。如果条目有 ,则开始下一个动画status:true
。
我们可以为每个动画添加延迟并立即运行它们。但是父级控制每个组件,每个组件在动画完成时通知,使得更新代码更加灵活。您可以根据状态为每个条目设置不同的动画。
我们可以使用 react-spring 动画库,但事情会变得复杂。CSS 动画是最简单的解决方案。
你可以试试这个
/* 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>
你也可以检查沙箱
在这里,我active
在所有li
元素中添加了类,但是如果您想激活两个步骤,则只应用前两个 li(即该类是有条件的)
可以为背景设置动画。请检查下面的示例
.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 类。