先上效果图
具体功能:
- 支持滚动、点击、日期选择、时间刻度间隔等
全部代码如下
<template>
<div class="yxkz-page-timer">
<div class="left-box">
<div class="left-bg" @click="prevTime">
<img src="./timepanel/img/prev.png" />
</div>
<div class="left-bg" @click="playTime">
<img
v-show="slidertimerStatus == false"
src="./timepanel/img/play.png"
/>
<img
v-show="slidertimerStatus == true"
src="./timepanel/img/pause.png"
/>
</div>
<div class="left-bg" @click="nextTime">
<img src="./timepanel/img/next.png" />
</div>
</div>
<div
class="time-container"
:style="{ width: (datetimes.length - 1) * 6 + 'px' }"
>
<div
class="time-line"
:style="{ width: (datetimes.length - 1) * 6 + 'px' }"
></div>
<div class="time-progress" :style="{ width: timeIndex * 6 + 'px' }"></div>
<div
class="time-ceng"
:style="{ width: (datetimes.length - 1) * 6 + 'px' }"
@click="handleSelectTime"
@mousemove="onMousemove"
></div>
<div
class="time-label"
:style="{ width: (datetimes.length - 1) * 6 + 'px' }"
>
<span v-for="(item, index) in datetimes" :key="index" class="label-box">
<div class="label-line" v-if="item.labelName != null"></div>
<span class="label-name">{{ item.labelName }}</span>
</span>
</div>
<span
class="time-btn"
:style="{ left: timeIndex * 6 - 13 + 'px' }"
@mousedown="onMousedown"
@mouseup="onMouseup"
>
<span class="time-btn-tip">{{
datetimes.length == 0 ? "" : datetimes[timeIndex].showTime
}}</span>
</span>
</div>
<div class="right-box">
<div class="step-box" style="position: relative">
<div class="step-name">间隔:</div>
<select
v-model="stepValue"
class="step-select"
@change="handleTimeStepChange"
>
<option
style="height: 20px; line-height: 20px"
v-for="item in timeleapList"
:value="item.value"
:key="item.value"
>
{{ item.label }}
</option>
</select>
</div>
<DatePicker
:open="open"
:value="datetime"
:options="options"
class="datetimepick"
type="date"
@on-change="handleDatetimeChange"
>
<a
href="javascript:void(0)"
@click="handleOpenDateOption"
class="datetimelink"
>
<template v-if="datetime === ''">选择时间</template>
<template v-else>{{ datetime }}</template>
<Icon type="md-arrow-dropdown" />
</a>
</DatePicker>
</div>
</div>
</template>
<script type="text/javascript">
import { DatePicker, Icon, Select, Option, Checkbox } from "iview";
//TODO:获取数据最新时间
import { getLatestTime } from "@/api/radar.js";
import { setTimeout, clearTimeout, setInterval, clearInterval } from "timers";
/**
* @description: 请求当前最新数据的时间 //TODO:暂时不对接借口
* @param {*}
* @return {*}
*/
export default {
components: {
DatePicker,
Icon,
Select,
Option,
Checkbox
},
// props: ["date"],
// watch: {
// date(val) {},
// },
data() {
return {
isDragging: false, // 是否滑动
timeIndex: 36, // 当前时间轴下标
datetimes: [], // 时间轴的时间列表
stepValue: 1, // 时间间隔
timeleapList: [
{ value: 1, label: "10min" },
{ value: 3, label: "30min" },
{ value: 6, label: "1h" },
{ value: 18, label: "3h" }
],
open: false, // 打开日期面板
options: {
// 日历插件快捷选取
shortcuts: [
{
text: "今天",
value() {
return new Date();
}
}
]
},
datetime: "", // 当前选中的日期
//TODO:自动播放
slidertimerStatus: false, // 是否开始播放
slidertimerInterval: null, // 定时器对象
speed: 2500, // 自动播放的速度
};
},
beforeMount() {},
mounted() {
let a = new Date(new Date().getTime() - 24 * 3600000);
let starttime = new Date(new Date(a).format("yyyy-MM-dd hh:00:00"));
let endtime = new Date(new Date().format("yyyy-MM-dd hh:mm:00"));
this.datetime = new Date().format("yyyy-MM-dd");
this.initDate(starttime, endtime, 1000 * 60 * 10, 0);
setInterval(() => {
this.autoRefresh();
}, 1000 * 60 * 5);
},
methods: {
autoRefresh() {
console.log('每隔5分钟时间轴刷新', new Date(new Date().format("yyyy-MM-dd hh:mm:00")))
let a = new Date(new Date().getTime() - 24 * 3600000);
let starttime = new Date(new Date(a).format("yyyy-MM-dd hh:00:00"));
let endtime = new Date(new Date().format("yyyy-MM-dd hh:mm:00"));
this.datetime = new Date().format("yyyy-MM-dd");
this.initDate(starttime, endtime, 1000 * 60 * 10, 0);
},
// 根据日期加载时间轴时间列表
initDate(startTime, endTime, step, initnew) {
var _datetimes = [];
for (var i = startTime.getTime(); i <= endTime.getTime(); i = i + step) {
let t = new Date(i);
let item = this.dateConversion(t);
_datetimes.push(item);
}
if (new Date().format("yyyy-MM-dd") == this.datetime) {
this.timeIndex = _datetimes.length - 1;
} else {
this.timeIndex = 0;
}
console.log("根据日期加载时间轴时间列表", _datetimes);
this.datetimes = _datetimes;
this.handleTimeLineIndex()
},
// 时间处理
dateConversion(item) {
var chinaStandard = item;
var date = new Date(chinaStandard);
var y = date.getFullYear();
var m = date.getMonth() + 1;
m = m < 10 ? "0" + m : m;
var d = date.getDate();
d = d < 10 ? "0" + d : d;
var h = date.getHours();
h = h < 10 ? "0" + h : h;
var minute = date.getMinutes();
minute = minute < 10 ? "0" + minute : minute;
let showTime = d + "日" + h + "时" + minute + "分"; //这里如果不需要小时 分 后边的可以不需要拼接
let labelTime = y + "-" + m + "-" + d + " " + h + ":" + minute + ":00";
let kItem = {
showTime: showTime,
labelTime: labelTime,
labelName: minute == "00" ? date.getHours() : null,
status: 1
};
return kItem;
},
// 时间发生变化
handleTimeLineIndex() {
console.log('时间轴变化的时间0000000', this.timeIndex)
console.log('时间轴变化的时间2222222', this.datetimes[this.timeIndex].labelTime)
this.$emit("changeDateTime", this.datetimes[this.timeIndex].labelTime);
},
// 单击时间轴
handleSelectTime(e) {
console.log("单击时间轴", e);
let offserWidth = e.offsetX;
this.timeIndex = Math.ceil(offserWidth / 6);
console.log("单击时间轴--timeIndex", this.timeIndex);
this.handleTimeLineIndex()
},
// 鼠标按下
onMousedown() {
console.log("鼠标按下");
this.isDragging = true;
},
// 鼠标松开
onMouseup() {
console.log("鼠标松开");
this.isDragging = false;
this.handleTimeLineIndex()
},
// 鼠标移动
onMousemove(e) {
if (this.isDragging == true) {
console.log("按钮左右滑动", e);
let offserWidth = e.offsetX;
this.timeIndex = Math.ceil(offserWidth / 6);
console.log("按钮左右滑动--timeIndex", this.timeIndex);
}
},
// 上一刻时间
prevTime() {
console.log("上一刻时间", this.timeIndex);
if (this.stepValue == 1) {
if (this.timeIndex > 0) {
this.timeIndex--;
this.handleTimeLineIndex()
}
} else if (this.stepValue == 3) {
if (this.timeIndex >= 3) {
this.timeIndex = this.timeIndex - this.stepValue;
this.handleTimeLineIndex()
}
} else if (this.stepValue == 6) {
if (this.timeIndex >= 6) {
this.timeIndex = this.timeIndex - this.stepValue;
this.handleTimeLineIndex()
}
} else if (this.stepValue == 18) {
if (this.timeIndex >= 18) {
this.timeIndex = this.timeIndex - this.stepValue;
this.handleTimeLineIndex()
}
}
},
// 开始播放或者暂停
playTime() {
this.slidertimerStatus = !this.slidertimerStatus;
clearInterval(this.slidertimerInterval);
if (this.slidertimerStatus == true) {
this.slidertimerInterval = setInterval(() => {
if (this.stepValue == 1) {
if (this.timeIndex < this.datetimes.length - 1) {
this.timeIndex++;
} else {
this.timeIndex = 0
}
} else if (this.stepValue == 3) {
if (this.timeIndex < this.datetimes.length - 3) {
this.timeIndex = this.timeIndex + this.stepValue;
} else if (this.timeIndex >= this.datetimes.length - 3 && this.timeIndex < this.datetimes.length - 1) {
this.timeIndex = this.datetimes.length - 1
} else {
this.timeIndex = 0
}
} else if (this.stepValue == 6) {
if (this.timeIndex < this.datetimes.length - 6) {
this.timeIndex = this.timeIndex + this.stepValue;
} else if (this.timeIndex >= this.datetimes.length - 6 && this.timeIndex < this.datetimes.length - 1) {
this.timeIndex = this.datetimes.length - 1
} else {
this.timeIndex = 0
}
} else if (this.stepValue == 18) {
if (this.timeIndex < this.datetimes.length - 18) {
this.timeIndex = this.timeIndex + this.stepValue;
} else if (this.timeIndex >= this.datetimes.length - 18 && this.timeIndex < this.datetimes.length - 1) {
this.timeIndex = this.datetimes.length - 1
} else {
this.timeIndex = 0
}
}
this.handleTimeLineIndex()
}, this.speed);
}
},
// 下一刻时间
nextTime() {
console.log("下一刻时间", this.timeIndex);
if (this.stepValue == 1) {
if (this.timeIndex < this.datetimes.length - 1) {
this.timeIndex++;
this.handleTimeLineIndex()
}
} else if (this.stepValue == 3) {
if (this.timeIndex < this.datetimes.length - 3) {
this.timeIndex = this.timeIndex + this.stepValue;
this.handleTimeLineIndex()
}
} else if (this.stepValue == 6) {
if (this.timeIndex < this.datetimes.length - 6) {
this.timeIndex = this.timeIndex + this.stepValue;
this.handleTimeLineIndex()
}
} else if (this.stepValue == 18) {
if (this.timeIndex < this.datetimes.length - 18) {
this.timeIndex = this.timeIndex + this.stepValue;
this.handleTimeLineIndex()
}
}
},
// 选择时间间隔
handleTimeStepChange(event) {
console.log("选中的时间间隔", event);
this.stepValue = parseInt(event.target.value);
},
// 打开日期面板
handleOpenDateOption() {
this.open = !this.open;
},
// 选中日期
handleDatetimeChange(date) {
console.log("选择的日期", date);
this.open = false;
if (new Date().format("yyyy-MM-dd") == date) {
console.log("选择的日期-----当天", date);
let a = new Date(new Date().getTime() - 24 * 3600000);
let starttime = new Date(new Date(a).format("yyyy-MM-dd hh:00:00"));
let endtime = new Date(new Date().format("yyyy-MM-dd hh:mm:00"));
this.datetime = new Date().format("yyyy-MM-dd");
this.initDate(starttime, endtime, 1000 * 600, 0);
} else {
console.log("选择的日期---不是当天的", date);
let starttime = new Date(date + " 00:00:00");
let endtime = new Date(
new Date(starttime.format("yyyy-MM-dd 00") + ":00:00").getTime() +
24 * 3600000
);
this.datetime = starttime.format("yyyy-MM-dd");
this.initDate(starttime, endtime, 1000 * 600, 1);
}
}
},
beforeDestroy() {
clearInterval(this.slidertimerInterval);
}
};
</script>
<style lang="scss" scoped>
.yxkz-page-timer {
position: absolute;
z-index: 600;
left: 20%;
bottom: 50px;
opacity: 0.9;
border-radius: 6px;
display: flex;
align-items: center;
padding: 2px 20px;
padding-left: 10px;
border-radius: none;
.left-box {
width: 100px;
display: flex;
justify-content: space-between;
align-items: center;
margin-right: 20px;
.left-bg {
display: flex;
justify-content: center;
align-items: center;
height: 23px;
width: 23px;
background: #013a67;
border: 1px solid #02a2fa;
border-radius: 50%;
cursor: pointer;
}
}
.time-container {
position: relative;
width: 100%;
height: 8px;
display: flex;
justify-content: space-between;
background: #cff;
border: 1px solid #000;
border-radius: 3px;
.time-line {
width: 100%;
height: 100%;
border-radius: 3px;
z-index: 1001;
}
.time-progress {
position: absolute;
left: 0;
top: 0;
height: 100%;
border-radius: 3px;
background: #00d8ff;
}
.time-ceng {
position: absolute;
left: 0;
top: 0;
height: 35px;
cursor: pointer;
z-index: 1002;
}
.time-label {
position: absolute;
left: 0;
top: 8px;
display: flex;
justify-content: space-between;
cursor: pointer;
.label-box {
width: 6px;
display: flex;
flex-direction: column;
align-items: center;
margin-left: -3px;
.label-line {
width: 1px;
height: 5px;
background: #00d8ff;
}
.label-name {
color: #44a8f6;
}
}
}
.time-btn {
position: absolute;
top: -9px;
width: 26px;
height: 26px;
border: 8px solid #fff;
border-radius: 50%;
background: #016cee;
box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.75);
z-index: 1010;
&:hover {
cursor: pointer;
.time-btn-tip {
top: -30px;
}
}
.time-btn-tip {
position: absolute;
opacity: 1;
top: -33px;
left: -42px;
width: 92px;
text-align: center;
border: none;
border-radius: 9px;
background: #013a67;
-webkit-box-shadow: 0 2px 3px 0 rgba(35, 64, 94, 0.24);
box-shadow: 0 2px 3px 0 rgba(35, 64, 94, 0.24);
color: #fff;
border: 1px solid #02a2fa;
// &::before {
// border-top-color: #02a2fa;
// }
&::after {
content: " ";
width: 0;
height: 0;
border: 5px solid hsla(0, 0%, 100%, 0);
border-top-color: #02a2fa;
position: absolute;
bottom: -10px;
left: 50%;
margin-left: -5px;
}
}
}
}
.right-box {
margin-left: 20px;
margin-top: 20px;
.step-box {
display: flex;
width: 105px;
height: 20px;
border-radius: 5px;
border: 1px solid #02a2fa;
background: #013a67;
.step-name {
color: #fff;
background: #004747;
padding-left: 10px;
}
.step-select {
border: 0;
color: #fff;
background: #013a67;
}
}
}
.right-box .datetimepick .datetimelink {
margin-top: 2px;
display: block;
height: 20px;
width: 105px;
color: #013a67;
text-align: center;
line-height: 20px;
background: #013a67;
color: #fff;
display: flex;
justify-content: space-between;
padding-left: 12px;
border: 1px solid #00d8ff;
border-radius: 5px;
margin-bottom: 5px;
}
.right-box .datetimepick .datetimelink i {
width: 22px;
height: 22px;
display: flex;
justify-content: center;
align-items: center;
// background-color: #38DE98;
}
.right-box .datetimepick .datetimelink i::before {
content: "";
width: 8px;
height: 8px;
border: 2px solid #00d8ff;
border-top: 0;
border-left: 0;
transform: rotate(45deg) scale(1);
transition: all 0.2s ease-in-out;
position: absolute;
top: 5px;
}
.right-box .datetimepick /deep/.ivu-date-picker-cells {
margin: 0;
}
.right-box .datetimepick /deep/ .ivu-date-picker-cells-header span {
color: #333;
color: #fff;
}
.right-box
.datetimepick
/deep/
.ivu-select-dropdown
span.ivu-date-picker-cells-cell {
height: 24px;
}
.right-box .datetimepick /deep/ .ivu-picker-panel-body {
background: #032155;
}
.right-box
.datetimepick
/deep/
.ivu-picker-panel-body
.ivu-date-picker-header
.ivu-date-picker-header-label {
color: #fff;
}
.right-box
.datetimepick
/deep/
.ivu-picker-panel-body
.ivu-picker-panel-content
span {
color: #2571a2;
}
.right-box .datetimepick /deep/ .ivu-picker-panel-body span > em {
&:hover {
background: #2d8cf0;
color: #fff;
}
}
.right-box
.datetimepick
/deep/
.ivu-picker-panel-body
.ivu-picker-panel-content
span.ivu-date-picker-cells-focused
> em {
background: #2d8cf0;
color: #fff !important;
}
.right-box
.datetimepick
/deep/
.ivu-picker-panel-body
.ivu-picker-panel-content
span.ivu-date-picker-cells-cell-next-month
> em {
color: #16415d;
}
.right-box
.datetimepick
/deep/
.ivu-picker-panel-body
.ivu-picker-panel-content
span.ivu-date-picker-cells-cell-next-month
> em {
&:hover {
color: #fff;
}
}
.right-box
.datetimepick
/deep/
.ivu-picker-panel-body
.ivu-picker-panel-content
span.ivu-date-picker-cells-cell-prev-month
> em {
color: #16415d;
}
.right-box
.datetimepick
/deep/
.ivu-picker-panel-body
.ivu-picker-panel-content
span.ivu-date-picker-cells-cell-prev-month
> em {
&:hover {
color: #fff;
}
}
.right-box
.datetimepick
/deep/
.ivu-picker-panel-body
span.ivu-date-picker-cells-cell-disabled {
background: #0b3a7e;
color: #c0c4cc;
}
.right-box
.datetimepick
/deep/
.ivu-picker-panel-body
span.ivu-date-picker-cells-cell-disabled
> em {
background: #0b3a7e;
color: #c0c4cc !important;
}
.right-box
.datetimepick
/deep/
.ivu-picker-panel-body
span.ivu-date-picker-cells-cell-disabled
> em {
&:hover {
background: #0b3a7e;
color: #c0c4cc !important;
}
}
}
</style>