济菏高速业务端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

192 lines
4.4 KiB

1 year ago
<template>
<div class='TimeLine1'>
<!-- 节点 -->
<div class="node" v-for="(item, index) in data" ref="nodeRefs">
<span class="top-label">
<slot name="bottom-label" :data="item">
{{ item.time }}
</slot>
</span>
<div class="center">
<div class="line" v-if="!index" />
<div class="circle" :style="{ '--active-color': !item.isActive ? normalColor : activeColor }"></div>
<div class="line" :style="{
width: `${nodeLinesWidth[index]}px`,
borderImage: getBorderImageStyle(item),
}" />
<!-- borderImage: `linear-gradient(90deg, ${item.isActive ? 'rgba(59, 216, 188, 1), rgba(29, 171, 215, 1)' : '#ccc, #ccc'}) 2 2`, -->
</div>
<slot name="bottom-label" :data="item">
<div class="bottom"
:style="{ backgroundImage: `url(${require(`./images/bg${item.isActive ? '-active' : ''}.svg`)})` }">
{{ item.label }}
</div>
</slot>
</div>
</div>
</template>
<script>
export default {
name: 'TimeLine1',
props: {
data: {
type: Array,
default: () => Array.from({ length: 15 }).map(() => ({
time: "16.36",
label: "阿发",
isActive: false
}))
},
activeColor: {
type: String,
default: "#39D5BF"
},
normalColor: {
type: String,
default: "#ccc"
},
lineActiveColor: {
type: String,
default: "linear-gradient(90deg, rgba(59, 216, 188, 1), rgba(29, 171, 215, 1)}) 2 2"
},
lineNormalColor: {
type: String,
default: null
}
},
data() {
return {
nodeLinesWidth: []
}
},
watch: {
data: {
handler(data) {
const nodeLinesWidth = [];
function getWidth(node) {
return node.offsetWidth / 2 - 6;
}
this.$nextTick(() => {
data.forEach((_, index) => {
if (index === data.length - 1) return;
nodeLinesWidth[index] = getWidth(this.$refs.nodeRefs[index]) + getWidth(this.$refs.nodeRefs[index + 1]);
// if (nodeLinesWidth[index] < 90) nodeLinesWidth[index] = void 0;
});
this.nodeLinesWidth = nodeLinesWidth;
})
},
immediate: true
}
},
methods: {
getBorderImageStyle(item) {
const linearColor = item.isActive ? (this.lineActiveColor || `${this.activeColor}, ${this.activeColor}`) : (this.lineNormalColor || `${this.normalColor}, ${this.normalColor}`)
return `linear-gradient(90deg, ${linearColor}) 2 2`
}
}
}
</script>
<style lang='scss' scoped>
.TimeLine1 {
color: #fff;
width: auto;
font-size: 14px;
// font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #FFFFFF;
display: flex;
flex-wrap: nowrap;
overflow: auto;
gap: 15px;
padding-left: 15px;
// -webkit-background-clip: text;
// -webkit-text-fill-color: transparent;
.node {
display: flex;
align-items: center;
// justify-content: center;
flex-direction: column;
gap: 3px;
min-width: 100px;
.top-label {
line-height: 16px;
height: 24px;
}
.center {
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
position: relative;
.circle {
border: 1px solid var(--active-color, #39D5BF);
border-radius: 50%;
width: 15px;
height: 15px;
position: relative;
&::before {
content: "";
position: absolute;
width: 72%;
height: 72%;
border-radius: 50%;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: var(--active-color, #39D5BF);
}
}
.line {
position: absolute;
width: 81px;
height: 0px;
opacity: 1;
border: 2px solid;
border-image: linear-gradient(90deg, rgba(59, 216, 188, 1), rgba(29, 171, 215, 1)) 2 2;
&:first-child {
right: calc(50% + 8px + 6px);
}
&:last-child {
left: calc(50% + 8px + 6px);
}
}
}
&:first-child,
&:last-child {
.line {
width: 60px;
}
}
.bottom {
line-height: 16px;
background-repeat: no-repeat;
background-size: 100% 100%;
min-width: 90px;
text-align: center;
padding: 6px 12px;
height: 27px;
}
}
}
</style>