效果图:
index.tsx
class TimeLine extends React.Component<any,any> {
constructor(props) {
super(props)
this.state = {
left:0,
curStepIndex:2
}
}
//时间轴事件
goleft = () => {
if(this.state.curStepIndex > 2){
this.setState({
left:this.state.left + (document.body.clientWidth / this.props.number),
curStepIndex:this.state.curStepIndex - 1
})
}
}
goRight = () => {
if(this.state.curStepIndex < this.props.breakOption.length){
this.setState({
left:this.state.left + (-document.body.clientWidth / this.props.number),
curStepIndex:this.state.curStepIndex + 1
})
}
}
render() {
let { style = {}, breakOption = {}, topTextStyle = {}, bottomTextStyle = {}, number = 5} = this.props
return (
<div>
<div className={styles.timeLineContainer} style={style}>
<div className={styles.timeLine} style={{borderTop:"3px solid #3ED2E2",left:this.state.left}}>
{
breakOption.map((item, index) => {
return <div key={index} className={styles.steps} style={{width:`calc(100vw / ${number})`}}>
<div className={`${styles.point} ${index <= this.state.curStepIndex ? styles.activePoint : ''}`}></div>
{
item.topText?
<div className={[styles.topBox,styles.box].join(' ')}>
{item.topIcon? <img className={[styles.topIcon,styles.icon].join(' ')} src={item.topIcon} alt="" />:''}
<div>
<p className={styles.title} style={item.topTextStyle?.title?item.topTextStyle?.title:{}}>{item.topText ? item.topText : ''}</p>
<p className={styles.description} style={item.topTextStyle?.description?item.topTextStyle?.description:{}}>{item.topDescription ? item.topDescription : ''}</p>
</div>
</div>:''
}
{
item.bottomText?
<div className={[styles.bottomBox,styles.box].join(' ')}>
{item.bottomIcon? <img className={[styles.bottomIcon,styles.icon].join(' ')} src={item.bottomIcon} alt="" />:''}
<div>
<p className={styles.title} style={item.bottomTextStyle?.title?item.bottomTextStyle?.title:{}}>{item.bottomText ? item.bottomText : ''}</p>
<p className={styles.description} style={item.bottomTextStyle?.description?item.bottomTextStyle?.description:{}}>{item.bottomDescription ? item.bottomDescription : ''}</p>
</div>
</div>:''
}
</div>
})
}
</div>
</div>
<div className={styles.timeLinebtnBox}>
<CaretLeftOutlined className={styles.rightBtn} onClick={this.goleft}/>
<CaretRightOutlined className={styles.leftBtn} onClick={this.goRight}/>
</div>
</div>
)}}
export default TimeLine
styles.module.scss
.timeLineContainer {
padding:250px 0;
position: relative;
user-select: none;
.timeLine {
padding: 0 100vw 0 50px;
border-radius: 2px;
transition: all .3s;
display:flex;
position:absolute;
}
.steps{
position:relative;
}
.point {
position: absolute;
left:0;
top: -8px;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #06187D;
box-shadow: 0 0 0 5px #D8D8D8;
}
.activePoint {
background-color: #67D9FF;
box-shadow: 0 0 0 5px #2093FF;
}
.box{
position: absolute;
left:4px;
height:150px;
padding-left:30px;
border-left:2px dashed #3ED2E2;
display:flex;
p{
margin-bottom: 0;
}
}
.topBox {
bottom: 14px;
}
.bottomBox {
top:4px;
align-items: flex-end;
}
.title{
font-size: 20px;
font-weight: bold;
line-height: 27px;
color:black;
margin-bottom:10px !important;
}
.description{
font-size:15px;
color:rgba(0,0,0,0.9)
}
.icon{
width:40px;
height:40px;
position:absolute;
}
.topIcon{
top:-40px;
left:-20px;
}
.bottomIcon{
top:150px;
left:-20px;
}
}
.timeLinebtnBox{
text-align: center;
.rightBtn,.leftBtn{
font-size:50px;
color:#2093FF;
}
}
页面调用
const breakOption=[
{
topText: '2022年1月',
topDescription:<Translate id="CompanyProfile.timeLine.description1">The only domestic framework LakeSoul open source</Translate>,
//国产唯一湖仓框架 LakeSoul 开源
topIcon:require('@site/static/companyProfile/icon1.png').default,
active: true,
},
{
bottomText: '2022年3月',
bottomDescription:<Translate id="CompanyProfile.timeLine.description2">One-stop machine learning platform MetaSpore open source</Translate>,
// 一站式机器学习平台MetaSpore开源
bottomIcon:require('@site/static/companyProfile/icon2.png').default,
active: true
},
{
topText: '2022年5月',
topDescription:<Translate id="CompanyProfile.timeLine.description3">AI development and production platform AlphalDE opens private beta</Translate>,
//AI开发生产平台AlphaIDE开放内测
topIcon:require('@site/static/companyProfile/icon3.png').default,
active: false,
},
{
bottomText: '2022年7月',
bottomDescription:<Translate id="CompanyProfile.timeLine.description4">The only domestic open-source LakeSoul 2.0 released</Translate>,
//国产唯一开源湖仓 LakeSoul 2.0 发布
bottomIcon:require('@site/static/companyProfile/icon4.png').default,
active: false
},
{
topText: '2022年8月',
topDescription:<Translate id="CompanyProfile.timeLine.description5">Jointly hold the Data Lake Flow Batch Integrated Performance Optimization Challenge with CCF.</Translate>,
//联合 CCF 共同举办数据湖流批一体性能优化挑战赛
topIcon:require('@site/static/companyProfile/icon5.png').default,
active: false
},
{
bottomText: '2022年9月',
bottomDescription:<Translate id="CompanyProfile.timeLine.description6">In cooperation with the Beijing University of Posts and Telecommunications laboratory, Prof.Wang Pengfei joined the MetaSpore open-source community.</Translate>,
//与北京邮电大学实验室达成合作,王鹏飞老师团队加入 MetaSpore 开源社区
bottomIcon:require('@site/static/companyProfile/icon6.png').default,
active: false
},
{
topText: '2022年10月',
topDescription:<Translate id="CompanyProfile.timeLine.description7">It is recommended to log in to Shopify, the largest independent site construction platform.</Translate>,
// 推荐 SaaS 产品登录最大独立站建站平台 Shopify
topIcon:require('@site/static/companyProfile/icon7.png').default,
active: false
},
{
bottomText: '2022年11月',
bottomDescription:<Translate id="CompanyProfile.timeLine.description8">Won the Zhongguancun high-tech enterprise certification</Translate>,
// 荣获中关村高新技术企业认证
bottomIcon:require('@site/static/companyProfile/icon8.png').default,
active: false
},
{
topText: '2022年12月',
topDescription:<Translate id="CompanyProfile.timeLine.description9">Intel "Innovation Master Cup" global Al Geek Challenge preliminary, rematch double top: Personalized recommendation SaaS service is coming to the major public cloud</Translate>,
// 英特尔“创新大师杯”全球AI极客挑战赛初赛、复赛双榜第一;个性化推荐 SaaS 服务即将登陆各大公有云
topIcon:require('@site/static/companyProfile/icon9.png').default,
active: false
},
{
bottomText: '2023年1月',
bottomDescription:<Translate id="CompanyProfile.timeLine.description10">It was awarded the Top 10 most potential start-up of the Heart of the Machine.</Translate>,
// 荣获机器之心最具潜力创业企业Top10
bottomIcon:require('@site/static/companyProfile/icon10.png').default,
active: false
},
]
const [number,setNumber] = useState(5)
useEffect(() => {
if(document.body.clientWidth<768){
setNumber(()=>{
return 2
})
}
},[])
...
<TimeLine breakOption={breakOption} number={number} className={styles.timeLine}/>
...
记录我的第一篇~
啊哈~