<template> <div class="tabs"></div> <div class="main"> <div class="menu panel"> <div class="menu-item"> <h2 class="tip">区域选择</h2> <el-row :gutter="12"> <el-col :span="8"><span @click="onRegionClick('jiangning')" :class="{'active': currentRegion === 'jiangning'}">江宁</span></el-col> <el-col :span="8"><span @click="onRegionClick('liuhe')" :class="{'active': currentRegion === 'liuhe'}">六合</span></el-col> <el-col :span="8"><span @click="onRegionClick('pukou')" :class="{'active': currentRegion === 'pukou'}">浦口</span></el-col> </el-row> </div> <!-- layertype --> <div class="menu-item"> <h2 class="tip">要素选择</h2> <el-row :gutter="12"> <el-col :span="24"><span @click="onElementClick('PBLH', '边界层高度')" :class="{'active': currentElement === 'PBLH'}">边界层高度</span></el-col> <el-col :span="24"><span @click="onElementClick('opticalthickness', '光学厚度')" :class="{'active': currentElement === 'opticalthickness'}">光学厚度</span></el-col> <el-col :span="24"><span @click="onElementClick('Lidar_ratio', '激光雷达比')" :class="{'active': currentElement === 'Lidar_ratio'}">激光雷达比</span></el-col> <el-col :span="24"><span @click="onElementClick('PM', '气溶胶PM')" :class="{'active': currentElement === 'PM'}">气溶胶PM</span></el-col> <el-col :span="24"><span @click="onElementClick('ext_plot', '消光系数')" :class="{'active': currentElement === 'ext_plot'}">消光系数</span></el-col> <el-col :span="24"><span @click="onElementClick('layertype', '云气溶胶分类')" :class="{'active': currentElement === 'layertype'}">云气溶胶分类</span></el-col> <el-col :span="24"><span @click="onElementClick('wv_plot', '水汽')" :class="{'active': currentElement === 'wv_plot'}">水汽</span></el-col> <el-col :span="24"><span @click="onElementClick('cloudheight', '云高')" :class="{'active': currentElement === 'cloudheight'}">云高</span></el-col> </el-row> </div> </div> <div class="container panel"> <div class="toolbar day-toolbar"> <div class="times"> <div class="time-item" v-for="(time, index) in times" :key="index" :class="{'active': currentTime === time.date}"> <span class="time" @click="onTimeClick(time, index)">{{time.day}}</span> </div> </div> <el-date-picker v-model="date" type="date" placeholder="请选择" :clearable="false" :editable="false" class="date-picker" @change="onChange"> </el-date-picker> <div class="control-btn"> <span @click="onPrevDayClick"><img src="/images/prev.png" /></span> <span @click="onNextDayClick"><img src="/images/next.png" /></span> </div> <div class="refresh-btn" @click="onRefreshClick"> <img src="/images/refresh.png" /> </div> <div class="btns-group"> <span @click="onPlayClick">{{isPlay ? '暂停动画' : '播放动画'}}</span> <a @click="onDownloadClick">下载动画</a> <a id="radarDownload" :href="downloadSrc" download style="display: none;">下载隐藏层</a> </div> </div> <div class="picture-view"> <span class="arrow arrow-prev" @click="onPrevImgClick"><img src="/images/prev-btn.png" /></span> <span class="arrow arrow-next" @click="onNextImgClick"><img src="/images/next-btn.png" /></span> <span class="save-btn" @click="onSaveClick" v-if="currentElement === 'PBLH'"><img src="/images/save.png" /></span> <a :href="downloadImgUrl" download class="save-btn" v-else><img src="/images/save.png" /></a> <div class="download-pictures" id="pictures" v-if="currentElement === 'PBLH'"> <a v-for="(url, index) in urls" :key="index" download></a> </div> <div class="picture-container raman-picture-container"> <!-- <h2 class="title">{{title}}</h2> --> <div class="picture"> <el-image :src="imgUrl" :preview-src-list="previewUrl" :initial-index="1" fit="contain" @load="onImageLoad" :class="{'pblh-image': currentElement === 'PBLH'}" > <template #error> <div class="image-slot"> <img src="/images/null-picture.png" /> </div> <p class="image-tip">暂无图片</p> </template> <template #placeholder> <div class="image-placeholder">正在加载...</div> </template> </el-image> <el-image :src="signalPBLHImgUrl" :preview-src-list="signalPBLHPreviewUrl" :initial-index="1" fit="contain" @load="onImageLoad" v-if="currentElement === 'PBLH'" :class="{'pblh-image': currentElement === 'PBLH'}" > <template #error> <div class="image-slot"> <img src="/images/null-picture.png" /> </div> <p class="image-tip">暂无图片</p> </template> <template #placeholder> <div class="image-placeholder">正在加载...</div> </template> </el-image> </div> </div> </div> </div> </div> </template> <script lang="ts"> import { onMounted, reactive, toRefs } from 'vue'; import moment from "moment"; import { RamanLidarConfig } from '../uilts/Config'; import { post } from '../uilts/axios'; export default { name: 'RamanLidar', setup() { let timer = null; let options = reactive({ currentRegion: 'jiangning', currentElement: 'PBLH', currentType: '边界层高度', date: moment('2021-11-15').format('YYYY-MM-DD'), times: [], currentTime: null, downloadImgUrl: '/images/default-picture.png', imgUrl: '/images/default-picture.png', signalPBLHImgUrl: '/images/default-picture.png', previewUrl: [], signalPBLHPreviewUrl: [], isPlay: false, title: null, index: 0, downloadSrc: null, urls: [] }) onMounted(() => { initTimeLine(); setTitle(moment(options.date, 'YYYY-MM-DD')); setTimeout(() => { activeImage(); }, 50); }) const onRegionClick = (region) => { options.currentRegion = region; options.date = options.currentTime; cancelActive(); setTitle(moment(options.date)); activeImage(); } const onElementClick = (element, type) => { options.currentElement = element; options.currentType = type; options.date = options.currentTime; cancelActive(); setTitle(moment(options.date)); activeImage(); } const setTitle = (date) => { options.title = date.format('YYYY.MM.DD') + ' ' + options.currentType; } const activeImage = () => { options.imgUrl = RamanLidarConfig.getUrl(options.currentRegion, options.currentElement, moment(options.currentTime, 'YYYY-MM-DD')); options.previewUrl = [options.imgUrl]; options.signalPBLHImgUrl = RamanLidarConfig.getUrl(options.currentRegion, 'signal_' + options.currentElement, moment(options.currentTime, 'YYYY-MM-DD')); options.signalPBLHPreviewUrl = [options.signalPBLHImgUrl]; } const onImageLoad = (event) => { if (event.currentTarget.getAttribute('src') !== '/images/default-picture.png') converToBase64(options.imgUrl); else return } const onDownloadClick = () => { post("/image/createGif", prepareParams(), 'application/json').then((response: any) => { if (response.error != 0){ console.log(response.message); return; } fetch(response.data).then(res => { return res.blob(); }).then(blob => { let reader = new FileReader(); reader.onloadend = function(){ options.downloadSrc = reader.result; setTimeout(() => { document.getElementById("radarDownload").click(); options.downloadSrc = null; }, 500); }; reader.readAsDataURL(blob); }).catch(console.error); }) } const prepareParams = () => { return { model: 'radar', station: options.currentRegion, elementCode: options.currentElement, type: null, time: moment(options.times[0].date).format("YYYYMMDDHHmmss") + '-' + moment(options.times[options.times.length - 1].date).format("YYYYMMDDHHmmss"), urls: prepareUrls() } } const prepareUrls = () => { let urls = []; for(let index = 0, len = options.times.length; index < len; index++){ let time = moment(options.times[index].date); if (options.currentElement === 'PBLH') { urls.push( RamanLidarConfig.getUrl(options.currentRegion, options.currentElement, time), RamanLidarConfig.getUrl(options.currentRegion, 'signal_' + options.currentElement, time) ); } else urls.push(RamanLidarConfig.getUrl(options.currentRegion, options.currentElement, time)); } console.log(urls) return urls; } const converToBase64 = (path) => { let img = new Image(); img.src = path; let canvas = document.createElement("canvas") as HTMLCanvasElement; canvas.width = img.width; canvas.height = img.height; let ctx = canvas.getContext("2d"); let base64 = ''; img.setAttribute("crossOrigin",'Anonymous') img.onload = function() { ctx.drawImage(img, 0, 0); base64 = canvas.toDataURL("image/png"); options.downloadImgUrl = base64; }; } const initTimeLine = () => { options.times = []; options.currentTime = moment(options.date).format('YYYY-MM-DD'); let now = moment(options.date).add(1, 'day'); for (let i = 0; i < 15 ; i++) { options.times.push({ day: now.add(-1, 'day').format('DD'), date: now.format('YYYY-MM-DD'), }) } options.times.reverse(); options.index = options.times.length - 1; } const onTimeClick = (time, index) => { options.currentTime = time.date; options.date = time.date; options.index = index; cancelActive(); setTitle(moment(time.date, 'YYYY-MM-DD')); activeImage(); } const cancelActive = () => { clearTimer(); options.isPlay = false; } const onPrevDayClick = () => { let element = getCurrentElement(); options.date = moment(options.date).add(-1, 'day').format('YYYY-MM-DD'); options.currentTime = options.date; options.index--; if (options.index < 0) { options.index = element.childElementCount - 1; options.date = options.times[options.times.length - 1].date } cancelActive(); setCurrentPlayElement(element) } const onNextDayClick = () => { options.date = moment(options.date).add(1, 'day').format('YYYY-MM-DD') } const onPrevImgClick = () => { let element = getCurrentElement(); options.index--; if (options.index < 0) options.index = element.childElementCount - 1; setCurrentPlayElement(element); } const onNextImgClick = () => { let element = getCurrentElement(); options.index++; if (options.index > element.childElementCount - 1) options.index = 0; setCurrentPlayElement(element); } const onRefreshClick = () => { options.date = moment('2021-11-15').format('YYYY-MM-DD'); options.currentTime = options.times[options.times.length - 1].date; cancelActive(); activeImage(); } const onPlayClick = () => { options.isPlay = !options.isPlay; if (options.isPlay) { timeExcute(); } else { clearTimer(); } } const timeExcute = () => { clearTimer(); let element = getCurrentElement();; timer = setInterval( () => { options.index++; if (options.index > element.childElementCount - 1) options.index = 0; setCurrentPlayElement(element); }, 5000) } const clearTimer = () => { if (timer) clearInterval(timer); } const getCurrentElement = () => { return document.querySelector('.times'); } const setCurrentPlayElement = (element) => { for(let i = 0; i < element.childElementCount; i++) element.children[i].classList.remove('active'); element.children[options.index].classList.add('active'); options.currentTime = options.times[options.index].date; setTitle(moment(options.times[options.index].date, 'YYYY-MM-DD')); activeImage(); } const onChange = () => { initTimeLine(); setTitle(moment(options.date)); activeImage(); } const onSaveClick = () => { let pictures = document.getElementById('pictures'); options.urls = [options.signalPBLHImgUrl, options.signalPBLHImgUrl, options.imgUrl]; for (let i = 0; i < options.urls.length; i++) { let img = new Image(); img.src = options.urls[i]; let canvas = document.createElement("canvas") as HTMLCanvasElement; canvas.width = img.width; canvas.height = img.height; let ctx = canvas.getContext("2d"); let base64 = ""; img.setAttribute("crossOrigin",'Anonymous'); img.onload = () => { ctx.drawImage(img, 0, 0); base64 = canvas.toDataURL("image/png"); pictures.children[i].setAttribute('href', base64); setTimeout(() => { let button: HTMLElement = pictures.children[i] as HTMLElement; button.click(); pictures.children[i].setAttribute('href', null); }, 500); }; } } return { ...toRefs(options), onRegionClick, onElementClick, onTimeClick, onPrevDayClick, onNextDayClick, onPrevImgClick, onNextImgClick, onRefreshClick, onPlayClick, onChange, onImageLoad, onDownloadClick, onSaveClick } } } </script> <style lang="less" scoped> .main { .container { .raman-picture-container { width: calc(~"100% - 1rem"); margin: 0 auto; .picture { .pblh-image { width: 50%; } } } } } </style>