wangyawei
2025-04-18 293cc038aef227332161532621b97c987d1b1661
src/components/menu/TimeLine.vue
@@ -1,32 +1,21 @@
<template>
  <div class="timeline-container">
    <div class="controls">
    <!-- <div @click="endSimulate">结束模拟</div> -->
      <!-- <div @click="endSimulate">结束模拟</div> -->
      <div class="control-btn" @click="skipBackward">
        <img
          src="@/assets/img/timeline/left.png"
          class="fas fa-step-backward"
        />
        <img src="@/assets/img/timeline/left.png" class="fas fa-step-backward" />
      </div>
      <div class="control-btn play-btn" @click="togglePlay">
        <img v-show="isPlaying" src="@/assets/img/timeline/stop.png" />
        <img v-show="!isPlaying" src="@/assets/img/timeline/start.png" />
      </div>
      <div class="control-btn" @click="skipForward">
        <img
          src="@/assets/img/timeline/right.png"
          class="fas fa-step-forward"
        />
        <img src="@/assets/img/timeline/right.png" class="fas fa-step-forward" />
      </div>
      <div class="speed-control">
        <div @click="toggleSpeedMenu">{{ playbackRate }}X</div>
        <div class="speed-menu" v-show="showSpeedMenu">
          <div
            v-for="rate in playbackRates"
            :key="rate"
            @click.capture="setPlaybackRate(rate)"
            :class="{ active: playbackRate === rate }"
          >
          <div v-for="rate in playbackRates" :key="rate" @click.capture="setPlaybackRate(rate)" :class="{ active: playbackRate === rate }">
            {{ rate }}X
          </div>
        </div>
@@ -35,35 +24,24 @@
    <div class="timeline">
      <div class="dates">
        <div
          v-for="(date, index) in visibleDates"
          :key="index"
          class="date-label"
        >
        <div v-for="(date, index) in visibleDates" :key="index" class="date-label">
          {{ formatDate(date) }}
        </div>
      </div>
      <div class="timeline-track" ref="timelineTrack" @click="seekToPosition">
        <div
          class="timeline-progress"
          :style="{ width: progressPercentage + '%' }"
        ></div>
        <div
          class="timeline-cursor"
          :style="{ left: progressPercentage + '%' }"
        ></div>
        <div class="timeline-progress" :style="{ width: progressPercentage + '%' }"></div>
        <div class="timeline-cursor" :style="{ left: progressPercentage + '%' }"></div>
        <div class="time-markers">
          <div
            v-for="(time, index) in timeMarkers"
            :key="index"
            class="time-marker"
          >
          <div v-for="(time, index) in timeMarkers" :key="index" class="time-marker">
            {{ time }}
          </div>
        </div>
      </div>
    </div>
    <video id="video" width="200px" height="200px" controls loop autoplay style="display: none;" crossorigin="anonymous">
      <source src="/video/waters-1024.webm" type="video/webm" />
    </video>
  </div>
</template>
@@ -71,6 +49,7 @@
import {
  ref,
  computed,
  nextTick,
  onUnmounted,
  onMounted,
  watch,
@@ -118,6 +97,7 @@
  return dayjs(props.waterSimulateParams.date[1]);
});
let playInterval = null;
let hlsEntity = null;
// 计算属性
const progressPercentage = computed(() => {
@@ -142,7 +122,37 @@
const currentTimeFormatted = computed(() => {
  return formatTime(currentTime.value);
});
// 使用视频创建Cesium实体
const createVideoEntity = () => {
  // 获取视频元素
  const videoElement = document.getElementById('video');
  if (!videoElement) {
    console.error("未找到视频元素");
    return;
  }
  // 移除可能存在的旧实体
  const existingEntity = window.earthCtrl.viewer.entities.getById('hls');
  if (existingEntity) {
    window.earthCtrl.viewer.entities.remove(existingEntity);
  }
  // 确保视频可见
  videoElement.style.display = 'block';
  // 创建新的视频实体
  hlsEntity = window.earthCtrl.viewer.entities.add({
    id: 'hls',
    rectangle: {
      coordinates: window.SmartEarth.Cesium.Rectangle.fromDegrees(
        116.546665, 40.507452, 116.7757891, 40.6834562
      ),
      material: videoElement,
      outline: true,
      outlineColor: window.SmartEarth.Cesium.Color.BLACK,
    },
  });
};
const togglePlay = () => {
  // 如果当前是停止状态且已经播放完毕,点击时重置时间
  if (!isPlaying.value && currentTime.value >= duration.value) {
@@ -153,15 +163,43 @@
  isPlaying.value = !isPlaying.value;
  emit("isPlaying", isPlaying.value);
  if (isPlaying.value) {
    startPlayback();
    // 如果是从头开始播放
    if (currentTime.value === 0) {
      emit("playbackFinished", false);
  // if (isPlaying.value) {
  //   startPlayback();
  //   // 如果是从头开始播放
  //   if (currentTime.value === 0) {
  //     emit("playbackFinished", false);
  //   }
  // } else {
  //   stopPlayback();
  // }
  // 新增代码:加视频流
  nextTick(() => {
    // 处理视频播放
    const videoElement = document.getElementById('video');
    if (videoElement) {
      if (isPlaying.value) {
        // 确保已创建视频实体
        createVideoEntity();
        // 播放视频
        videoElement.play().catch(e => {
          console.error("视频播放失败:", e);
        });
      } else {
        // 暂停视频
        videoElement.pause();
      }
    }
  } else {
    stopPlayback();
  }
    if (isPlaying.value) {
      startPlayback();
      // 如果是从头开始播放
      if (currentTime.value === 0) {
        emit("playbackFinished", false);
      }
    } else {
      stopPlayback();
    }
  });
};
const startPlayback = () => {
@@ -179,7 +217,13 @@
      emit("isPlaying", isPlaying.value); // 通知播放状态变化
      emit("playbackFinished", true); // 通知播放完成
      emit("timeUpdate", progressPercentage.value); // 更新进度条位置
      // 播放结束时暂停视频
      const videoElement = document.getElementById('video');
      if (videoElement) {
        videoElement.pause();
      }
    }
    // 暂停视频
    emit("timeUpdate", progressPercentage.value);
  }, 1000);
@@ -209,6 +253,11 @@
  playbackRate.value = rate;
  showSpeedMenu.value = false;
  // 同步视频播放速率
  const videoElement = document.getElementById('video');
  if (videoElement) {
    videoElement.playbackRate = rate;
  }
  if (isPlaying.value) {
    stopPlayback();
    startPlayback();
@@ -239,7 +288,7 @@
};
const rainFallData = ref([]);
function getRainfallData() {
function getRainfallData () {
  getRainfall().then((res) => {
    // rainFallData.value = res.data.map(item => {
    //   return dayjs(item.time).format("HH:mm")
@@ -254,7 +303,7 @@
let mockTimer = null;
let currentRainfall = ref(0.0001);
function randomMockWater() {
function randomMockWater () {
  let delay = (3 / playbackRate.value) * 1000;
  if (delay < 1000) {
    delay = 1000;
@@ -271,7 +320,7 @@
    if (rainfall && rainfall.total) {
      // console.log(rainfall.total);
      createWaterPrimitive(rainfall.total / 50000);
      //  createWaterPrimitive(rainfall.total / 50000);
    }
  }, delay);
}