项目需要按天播放地图等值线图功能,所以需要一个时间进度条,网上找了一下发现没有自己需要的样子,于是只能简单的写一个。

1、封装时间尺度组件

<!-- 时间尺度 -->
<template>
	<div class="time">
		<div class="time_menu" v-show="timeList.length != 0">
			<template v-if="playState">
				<el-tooltip class="item" effect="dark" content="暂停" placement="top-end">
					<img src="../assets/timescale/zt.png" @click="playState = false,stopInterval()" />
				</el-tooltip>
			</template>
			<template v-if="!playState">
				<el-tooltip class="item" effect="dark" content="播放" placement="top-end">
					<img src="../assets/timescale/bf.png" @click="playState = true,startInterval()" />
				</el-tooltip>
			</template>
			<el-tooltip class="item" effect="dark" content="上一天" placement="top-end">
				<img src="../assets/timescale/icons_next.png" @click="upTime()" style="transform: rotate(180deg);" />
			</el-tooltip>
			<el-tooltip class="item" effect="dark" content="下一天" placement="top-end">
				<img src="../assets/timescale/icons_next.png" @click="nextTime()" />
			</el-tooltip>
		</div>
		<div style="width: 80%;height: 100%;position: relative;display: flex;align-items: flex-end;overflow: auto;">
			<div style="height: 40%;display: flex;flex-shrink: 0;flex-flow: row nowrap;align-items: flex-end;">
				<template v-for="(item,index) in timeList">
					<el-tooltip class="item" effect="dark" :content="item" placement="top-end">
						<div class="keDuXian" :style="index%5 == 0 ? 'height:100%;':'height:60%;'" :id="item"
							@click="timeClick(item)">
							<template v-if="index > 0">
							<div v-if="index%5 == 0" style="position: relative;top: -20px;left:-30px;color: #FFF;width: 70px;font-size: 0.75rem;">
								{{item}}
							</div>
							</template>
							</div>
					</el-tooltip>
				</template>
			</div>
			<div v-show="timeList.length != 0" class="progress" :style="'width:'+progresswidth+'px;'">
				<div style="width: 100%;height: 40%;background-color: rgb(20,170,255);">
				</div>
			</div>
			<img v-show="timeList.length != 0" src="../assets/timescale/xsjx.png" class="progressImg" :style="'left:'+(progresswidth == 0 ? -7 : (progresswidth-8))+'px;'" />
		</div>
	</div>
</template>

<script>
	import {getScopeTime} from "../utils/regular.js"
	export default {
		data() {
			return {
				timeList:[],
				thisTime: '',
				progresswidth: 0,
				playState: false,
				Interval:'',
			}
		},
		beforeDestroy(){
			clearInterval(this.Interval)
		},
		methods: {
			startInterval(){
				this.Interval = setInterval(() => {
					if(this.timeList.indexOf(this.thisTime)+1 == this.timeList.length){
						this.playState =  false
						this.stopInterval()
					}else{
						this.thisTime = this.timeList[this.timeList.indexOf(this.thisTime) + 1]
					}
					this.setProgressWidth()
				}, 4000)
			},
			stopInterval(){
				clearInterval(this.Interval)
			},
			init(time,start,end) {
				this.timeList = getScopeTime(start,end,2)
				this.thisTime = time
				this.$nextTick(()=>{
					this.setProgressWidth()
				})
			},
			timeClick(time) {
				this.thisTime = time
				this.setProgressWidth()
			},
			setProgressWidth(){
				this.progresswidth = document.getElementById(this.thisTime).offsetLeft
				this.$emit('schedule',this.thisTime)
			},
			upTime(){
				if(this.thisTime == this.timeList[0]){
					this.$message({
						message: '已经是第一天了',
						type: 'warning'
					});
				}else{
					this.thisTime = this.timeList[this.timeList.indexOf(this.thisTime)-1]
					this.setProgressWidth()
				}
			},
			nextTime(){
				if(this.thisTime == this.timeList[this.timeList.length-1]){
					this.$message({
						message: '已经是最后一天了',
						type: 'warning'
					});
				}else{
					this.thisTime = this.timeList[this.timeList.indexOf(this.thisTime)+1]
					this.setProgressWidth()
				}
			}
		}
	}
</script>

<style lang="less" scoped>
	.time {
		width: 100%;
		height: 100%;
		background: rgba(10, 34, 66, 0.65);
		box-shadow: inset 0px 1px 12px 0px rgba(75, 137, 255, 0.5);
		border-radius: 4px;
		border: 1px solid #57C8EE;
		display: flex;
		align-items: flex-end;
		position: relative;
	}

	.time_menu {
		width: 20%;
		height: 100%;
		display: flex;
		align-items: center;
		justify-content: space-evenly;
		padding: 0 3%;
		box-sizing: border-box;

		img {
			width: 20px;
			height: 20px;
			cursor: pointer;
			transition-duration: 0.5s;
		}
	}

	.progress {
		height:100%;
		position: absolute;
		display: flex;
		align-items: flex-end;
		z-index: -1;
		transition-duration: 0.5s;
	}

	.triangle {
		width: 0px;
		height: 0px;
		border: 20px solid transparent;
		border-top-color: #00FFFF;
		// opacity: 1;
		position: absolute;
		left: -20px;
		top: 20px;
	}
	.keDuXian{
		width: 2px;
		background-color: #FFF;
		cursor: pointer;
		margin-right:25px;
	}
	.progressImg{
		width: 1.125rem;
		height: 1.125rem;
		position: absolute;
		z-index:9;
	}
</style>

2、在vue页面使用时间尺度 

首先引入组件 然后给组件外部包一层div  组件的大小是根据父级来的

初始化:在methods方法里调用组件内部的init方法初始化 传入三个参数

schedule事件是每当尺度变化会返回变化后的时间,可以根据时间做对应逻辑处理

<!-- 进度条-->
<div style="width: 50%;height: 4%;position: absolute;z-index: 999;bottom: 20%;left: 25%;">
   <timescale ref="timescale" @schedule="schedule"></timescale>
</div>

<!-- 引入组件-->
import timescale from "../../components/timeScale.vue"



<!-- 调用组件内部方法 初始化时间尺度  传入选中时间 起时间 止时间-->
this.$refs.timescale.init(this.isOlineTime,this.selectSectionTime[0],getTomorrow(this.selectSectionTime[1]))

3、组件init方法内 通过起止时间算出中间的所有时间尺度 

startTime:开始时间

endTime:结束时间

type:1按日返回小时 2按月返回每天 

export const getScopeTime = (startTime, endTime, type) => {
	let start = new Date(startTime).getTime()
	let end = new Date(endTime).getTime()
	let time = []
	if (type == 2) {
		for (var i = 0; i < 1; i--) {
			start += 86400000
			if (start == end) {
				time.unshift(startTime.split(' ')[0])
				break
			} else {
				time.push(unixTimeToDateTime(start).split(' ')[0])
			}
		}
	} else if (type == 1) {
		for (var i = 0; i < 1; i--) {
			start += 3600000
			if (start == end) {
				time.unshift(startTime.split(' ')[0])
				break
			} else {
				time.push(unixTimeToDateTime(start))
			}
		}
	}

	return time
}

附上效果图

目前没有实现拖拽功能,只能通过点击刻度更换时间,或者自动播放。

有不懂的可以留言,看见了会解答,时间仓促,有bug请见谅。

时间尺度 https://www.aliyundrive.com/s/CCnhMFwbdEZ 提取码: 53mp 

有疑问可以加QQ:1327694945 备注CSDN

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐