index.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <template>
  2. <div class="timeControlBox">
  3. <el-slider
  4. style="width: 96%"
  5. v-model="sTimeRange"
  6. :min="0"
  7. :max="sliderMax"
  8. size="small"
  9. placement="bottom"
  10. range
  11. :marks="marks"
  12. :format-tooltip="sliderFormatTooltip"
  13. :disabled="isPlay"
  14. @input="sliderChange"
  15. />
  16. <el-progress
  17. class="timeControlProgress"
  18. :style="`left:${progressLeft}%; width:${progressWidth}%`"
  19. :text-inside="true"
  20. striped
  21. striped-flow
  22. indeterminate
  23. :duration="80"
  24. :stroke-width="6"
  25. :percentage="percentage"
  26. :format="progressFormat"
  27. />
  28. <el-button
  29. class="playBtn"
  30. :icon="isPlay ? VideoPause : VideoPlay"
  31. size="small"
  32. circle
  33. @click="playProgress"
  34. />
  35. </div>
  36. </template>
  37. <script>
  38. import cloud from "/public/static/exportData/cloud/layer.json";
  39. import rainJson from "/public/static/exportData/rain/layer.json";
  40. import tempJson from "/public/static/exportData/tmp/layer.json";
  41. import windJson from "/public/static/exportData/wind/layer.json";
  42. import { VideoPlay, VideoPause } from "@element-plus/icons-vue";
  43. import { ElMessage } from "element-plus";
  44. export default {
  45. props: {
  46. mode: {
  47. type: String,
  48. default: () => {
  49. return "";
  50. },
  51. },
  52. },
  53. data() {
  54. return {
  55. sTimeRange: [0, 0],
  56. sliderMax: 0,
  57. progressLeft: 0,
  58. progressWidth: 96,
  59. percentage: 0,
  60. marks: {},
  61. cloudJson: [],
  62. setpLeft: 1,
  63. VideoPlay,
  64. VideoPause,
  65. isPlay: false,
  66. playRange: [0, 0],
  67. };
  68. },
  69. created() {
  70. this.cloudJson = cloud.reverse();
  71. this.controlMode = this.mode || "";
  72. this.sliderMax = this.cloudJson.length - 1;
  73. this.sTimeRange = [0, this.sliderMax];
  74. let marks = {};
  75. this.cloudJson.forEach((ele, index) => {
  76. if (index % 2 === 0) {
  77. marks[index] = ele.date.split(" ")[1];
  78. }
  79. });
  80. this.marks = marks;
  81. },
  82. unmounted() {
  83. clearInterval(this.progressTimmer);
  84. this.progressTimmer = null;
  85. },
  86. methods: {
  87. sliderFormatTooltip(value) {
  88. let descStr = "";
  89. if (value === this.sTimeRange[0]) {
  90. descStr = "起始时间: ";
  91. } else if (value === this.sTimeRange[1]) {
  92. descStr = "截止时间: ";
  93. }
  94. return `${descStr}${this.cloudJson[value].date}`;
  95. },
  96. progressFormat() {
  97. return this.cloudJson[this.sTimeRange[0] + (this.setpLeft - 1)].date;
  98. },
  99. sliderChange(value) {
  100. this.progressLeft = parseFloat(
  101. (value[0] / (this.cloudJson.length - 1)) * 96
  102. );
  103. this.progressWidth =
  104. (value[1] / (this.cloudJson.length - 1)) * 96 - this.progressLeft;
  105. this.percentage = 0;
  106. },
  107. playProgress() {
  108. this.isPlay = !this.isPlay;
  109. if (this.isPlay) {
  110. const setpRight = this.sTimeRange[1];
  111. const st = this.cloudJson[this.sTimeRange[0]].date;
  112. const et = this.cloudJson[setpRight].date;
  113. if (
  114. this.playRange[0] !== this.sTimeRange[0] ||
  115. this.playRange[1] !== this.sTimeRange[1]
  116. ) {
  117. const [l, r] = this.sTimeRange;
  118. this.playRange = [l, r];
  119. this.setpLeft = 1;
  120. }
  121. ElMessage({
  122. type: "primary",
  123. plain: true,
  124. showClose: true,
  125. message: `开始回滚 ${st} ~ ${et} 之间的数据`,
  126. });
  127. const scrollRange = this.sTimeRange[1] + 1 - (this.sTimeRange[0] + 1);
  128. this.progressTimmer = setInterval(() => {
  129. if (this.setpLeft > scrollRange) {
  130. this.setpLeft = 0;
  131. }
  132. let p = parseInt((this.setpLeft / scrollRange) * 100);
  133. this.percentage = p >= 100 ? 100 : p;
  134. this.setpLeft++;
  135. }, 1000);
  136. } else {
  137. clearInterval(this.progressTimmer);
  138. this.progressTimmer = null;
  139. }
  140. },
  141. },
  142. watch: {
  143. mode(val) {
  144. this.controlMode = val;
  145. },
  146. },
  147. };
  148. </script>
  149. <style lang="less" scoped>
  150. .timeControlBox {
  151. position: relative;
  152. width: 100%;
  153. .timeControlProgress {
  154. position: absolute;
  155. top: 9px;
  156. user-select: none;
  157. pointer-events: none;
  158. }
  159. .playBtn {
  160. position: absolute;
  161. right: 0;
  162. top: 0;
  163. width: 32px;
  164. height: 32px;
  165. background: rgba(0, 0, 0, 0, 0.5);
  166. border: 0;
  167. }
  168. }
  169. </style>
  170. <style lang="less">
  171. .timeControlBox {
  172. .el-slider__marks {
  173. .el-slider__marks-text {
  174. color: #e4e7ed;
  175. text-shadow: 2px 2px 0 #000;
  176. }
  177. }
  178. .el-progress-bar__outer {
  179. overflow: visible;
  180. }
  181. .el-progress-bar__innerText {
  182. background: #303133;
  183. font-size: 12px;
  184. padding: 5px 10px;
  185. border-radius: 8px;
  186. margin: 0;
  187. position: relative;
  188. bottom: 28px;
  189. left: 57px;
  190. }
  191. .el-slider__bar {
  192. background: transparent;
  193. }
  194. .playBtn {
  195. .el-icon {
  196. font-size: 42px;
  197. svg {
  198. color: #fff;
  199. }
  200. }
  201. }
  202. }
  203. </style>