123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- <template>
- <div>
- <div class="time-axis-container" :style="{ bottom: `${dragState.bottom}px`, left: `${dragState.left}px` }">
- <div class="expand-btn" @click="changeExpand">{{ timeAxisState.expand ? '收起' : '展开' }}</div>
- <div v-show="timeAxisState.expand" class="time-box">
- <div class="time-picker-box">
- <el-date-picker
- v-model="timeAxisState.startTime"
- type="datetime"
- :editable="false"
- :format="timeAxisState.format"
- :value-format="timeAxisState.format"
- :clearable="false"
- />
- <el-date-picker
- v-model="timeAxisState.endTime"
- type="datetime"
- :editable="false"
- :format="timeAxisState.format"
- :value-format="timeAxisState.format"
- :clearable="false"
- />
- </div>
- <div class="time-list-box">
- <el-timeline>
- <el-timeline-item
- v-for="(activity, index) in timeAxisState.data"
- :key="index"
- :class="timeAxisState.activeIndex === index ? 'active' : ''"
- :timestamp="activity.time"
- />
- </el-timeline>
- </div>
- <div class="time-tool">
- <div class="prevIcon" @click="toPrevTime" />
- <div class="playIcon" @click="toPlayTime" />
- <div class="nextIcon" @click="toNextTime(true)" />
- <div class="speed-btn" @click="changeSpeed">{{ timeAxisState.speed === 1 ? 'x1' : 'x2' }}</div>
- <div class="rankIcon" @mousedown="startDrag" @mousemove="onDrag" @mouseup="stopDrag" @click="dragMove" />
- </div>
- </div>
- </div>
- <Dialog v-model="timeAxisState.showDialog" title="气象图" hide-footer @close="dialogClose">
- <img v-show="timeAxisState.activeIndex > -1" :src="timeAxisState.data[timeAxisState.activeIndex]?.img" style="width: 100%" />
- </Dialog>
- </div>
- </template>
- <script lang="ts" setup name="TimeAxis">
- import { parseTime } from '@/utils/ruoyi';
- import Dialog from '@/components/Dialog/index.vue';
- import img1 from './tempImg/img1.jfif';
- import img2 from './tempImg/img2.jfif';
- import img3 from './tempImg/img3.jfif';
- import img4 from './tempImg/img4.jfif';
- import img5 from './tempImg/img5.jfif';
- import img6 from './tempImg/img6.jfif';
- import img7 from './tempImg/img7.jfif';
- import img8 from './tempImg/img8.jfif';
- import img9 from './tempImg/img9.jfif';
- import img10 from './tempImg/img10.jfif';
- const containerScale = inject('containerScale');
- const timeAxisState = reactive({
- expand: false,
- format: 'YYYY-MM-DD HH:mm',
- startTime: '',
- endTime: '',
- activeIndex: -1,
- playing: false,
- show: false,
- showDialog: false,
- speed: 1,
- data: [
- {
- time: '00:15',
- img: img1
- },
- {
- time: '01:15',
- img: img2
- },
- {
- time: '01:45',
- img: img3
- },
- {
- time: '02:15',
- img: img4
- },
- {
- time: '03:15',
- img: img5
- },
- {
- time: '04:15',
- img: img6
- },
- {
- time: '05:15',
- img: img7
- },
- {
- time: '06:15',
- img: img8
- },
- {
- time: '07:15',
- img: img9
- },
- {
- time: '07:45',
- img: img10
- }
- ]
- });
- let timer;
- // 展开收起
- const changeExpand = () => {
- timeAxisState.expand = !timeAxisState.expand;
- };
- // 设置初始时间
- const getInitTime = () => {
- // 获取当前时间
- const now = new Date();
- timeAxisState.endTime = parseTime(now.getTime(), '{y}-{m}-{d} {h}:{i}');
- // 计算12小时前的时间
- now.setHours(now.getHours() - 12);
- timeAxisState.startTime = parseTime(now.getTime(), '{y}-{m}-{d} {h}:{i}');
- };
- // 返回上一个时间点
- const toPrevTime = () => {
- timeAxisState.showDialog = true;
- timeAxisState.playing = false;
- if (timeAxisState.activeIndex === 0) {
- timeAxisState.playing = false;
- } else {
- timeAxisState.activeIndex -= 1;
- }
- };
- // 播放
- const toPlayTime = () => {
- timeAxisState.playing = true;
- if (timeAxisState.activeIndex === timeAxisState.data.length - 1) {
- timeAxisState.activeIndex = -1;
- }
- loopPlay();
- };
- // 循环播放
- const loopPlay = () => {
- if (timeAxisState.playing === false) return;
- toNextTime();
- // && timeAxisState.activeIndex < timeAxisState.data.length - 1
- if (timeAxisState.playing) {
- setTimeout(loopPlay, 1000 / timeAxisState.speed);
- }
- };
- // 前往下一个时间点
- const toNextTime = (flag?: boolean) => {
- timeAxisState.showDialog = true;
- if (flag) {
- timeAxisState.playing = false;
- } else if (!timeAxisState.playing) {
- return;
- }
- if (timeAxisState.activeIndex === timeAxisState.data?.length - 1) {
- timeAxisState.playing = false;
- } else {
- timeAxisState.activeIndex += 1;
- }
- };
- // 更换倍速
- const changeSpeed = () => {
- timeAxisState.speed = timeAxisState.speed === 1 ? 2 : 1;
- };
- // 拖拽移动位置
- const dragMove = () => {};
- // 弹窗关闭后
- const dialogClose = () => {
- timeAxisState.playing = false;
- };
- // 拖拽的参数
- const dragState = reactive({
- bottom: 180,
- left: 200,
- dragging: false,
- startX: 20,
- startY: 20,
- initialMouseX: 20,
- initialMouseY: 20
- });
- // 开始拖拽
- const startDrag = (event) => {
- dragState.dragging = true;
- dragState.startX = dragState.left;
- dragState.startY = dragState.bottom;
- dragState.initialMouseX = event.clientX;
- dragState.initialMouseY = event.clientY;
- document.addEventListener('mousemove', onDrag);
- document.addEventListener('mouseup', stopDrag2);
- };
- const onDrag = (event) => {
- if (!dragState.dragging) return;
- console.log(dragState.bottom + dragState.initialMouseY - event.clientY);
- console.log(dragState.bottom, dragState.initialMouseY, event.clientY);
- let left = (dragState.startX + event.clientX - dragState.initialMouseX) / containerScale().scaleX - 134;
- let bottom = (dragState.startY + dragState.initialMouseY - event.clientY) / containerScale().scaleY - 134;
- // // 检测是否溢出
- // if (left < 0) {
- // left = 0;
- // } else if (left > document.body.clientWidth - 1001) {
- // left = document.body.clientWidth - 1001;
- // }
- // if (bottom < 0) {
- // bottom = 0;
- // } else if (bottom > document.body.clientHeight - 70) {
- // bottom = document.body.clientHeight - 70;
- // }
- dragState.left = left;
- dragState.bottom = bottom;
- };
- const stopDrag = () => {
- dragState.dragging = false;
- };
- const stopDrag2 = () => {
- dragState.dragging = false;
- document.removeEventListener('mousemove', onDrag);
- document.removeEventListener('mouseup', stopDrag2);
- };
- onMounted(() => {
- getInitTime();
- });
- </script>
- <style lang="scss" scoped>
- .time-axis-container {
- position: absolute;
- z-index: 2;
- color: #fff;
- font-size: 16px;
- height: 131px;
- display: flex;
- &::before {
- content: '';
- position: absolute;
- top: 50%;
- left: -15px;
- transform: translateY(-50%);
- width: 9px;
- height: 142px;
- background: url('@/assets/images/timeAxis/timeLeft.png') no-repeat;
- background-size: 100% 100%;
- }
- &::after {
- content: '';
- position: absolute;
- top: 50%;
- right: -15px;
- transform: translateY(-50%);
- width: 9px;
- height: 142px;
- background: url('@/assets/images/timeAxis/timeRight.png') no-repeat;
- }
- .expand-btn {
- width: 61px;
- height: 131px;
- background: url('@/assets/images/timeAxis/timeBtn.png') no-repeat;
- display: flex;
- justify-content: center;
- align-items: center;
- padding: 0 16px;
- cursor: pointer;
- font-size: 30px;
- }
- .time-box {
- width: 2640px;
- height: 158px;
- background: url('@/assets/images/timeAxis/timeAxis.png') no-repeat;
- display: flex;
- }
- .time-picker-box {
- width: 257px;
- display: flex;
- justify-content: center;
- align-items: center;
- flex-direction: column;
- padding: 10px;
- :deep(.el-date-editor.el-input) {
- width: 257px;
- height: 50px;
- font-size: 30px;
- }
- :deep(.el-input__wrapper) {
- background-color: transparent;
- border: unset;
- box-shadow: unset;
- }
- :deep(.el-input__inner) {
- color: #b5dbfc;
- cursor: pointer;
- }
- :deep(.el-input__prefix) {
- display: none;
- }
- }
- .time-list-box {
- flex: 1;
- display: flex;
- align-items: flex-end;
- overflow-x: auto;
- padding: 0 20px;
- .active {
- :deep(.el-timeline-item__node) {
- background-color: #ff0000;
- box-shadow: 0 0 8px 8px #f68686;
- }
- }
- :deep(.el-timeline) {
- display: flex;
- align-items: center;
- width: 100%;
- height: 100%;
- padding-top: 30px;
- }
- :deep(.el-timeline-item__tail) {
- height: 13px;
- //background-color: #1f54b6;
- background-image: linear-gradient(to bottom, #1064d6 10%, #1876be 50%, #1064d6 90%);
- width: 100%;
- position: absolute;
- top: 3px;
- }
- :deep(.el-timeline-item__wrapper) {
- top: 10px;
- left: -42px;
- padding-left: 0;
- }
- :deep(.el-timeline-item__timestamp) {
- font-size: 30px;
- color: #ffffff;
- font-family: 'PingFang SC', sans-serif;
- margin-top: 33px;
- }
- :deep(.el-timeline-item__node) {
- background-color: #ffffff;
- box-shadow: 0 0 8px 8px #569eff;
- width: 16px !important;
- height: 16px !important;
- }
- :deep(.el-timeline-item) {
- width: 120px;
- min-width: 120px;
- }
- }
- .time-tool {
- width: 457px;
- display: flex;
- align-items: center;
- padding: 0 5px;
- .tool-icon {
- margin-right: 5px;
- cursor: pointer;
- font-size: 20px;
- }
- .speed-btn {
- margin-right: 5px;
- color: #ffffff;
- cursor: pointer;
- font-size: 40px;
- padding-bottom: 10px;
- font-family: 'PingFang SC', sans-serif;
- }
- .prevIcon {
- width: 69px;
- height: 73px;
- background: url('@/assets/images/timeAxis/prev.png') no-repeat;
- cursor: pointer;
- }
- .playIcon {
- width: 93px;
- height: 93px;
- background: url('@/assets/images/timeAxis/play.png') no-repeat;
- cursor: pointer;
- }
- .nextIcon {
- width: 69px;
- height: 73px;
- background: url('@/assets/images/timeAxis/next.png') no-repeat;
- cursor: pointer;
- }
- .rankIcon {
- width: 104px;
- height: 104px;
- background: url('@/assets/images/timeAxis/rank.png') no-repeat;
- cursor: pointer;
- margin-left: 50px;
- }
- }
- }
- </style>
|