From fcb7d9aad38db5263426e3255ab88604ec60d8ca Mon Sep 17 00:00:00 2001
From: wangjuncheng <1>
Date: 星期一, 30 六月 2025 10:17:56 +0800
Subject: [PATCH] 修改颜色

---
 src/utils/water.js               |    2 
 src/components/menu/TimeLine.vue |  324 ++++++++++++++++++++++++++---------------------------
 2 files changed, 161 insertions(+), 165 deletions(-)

diff --git a/src/components/menu/TimeLine.vue b/src/components/menu/TimeLine.vue
index f4b1380..0c97f87 100644
--- a/src/components/menu/TimeLine.vue
+++ b/src/components/menu/TimeLine.vue
@@ -527,172 +527,188 @@
 
   return timeStepHours;
 }
+// ============================================================================
+// 浼樺寲鏂瑰紡锛屽彲浠ユ眰鍑烘暣涓椂闂磋酱涓婏紝绗竴娆¢亣鍒拌繖鍏釜闃堝�煎緱鏃堕棿鐐癸紝鐒跺悗鍒嗘椂闂存鏄剧ず锛宎鏃堕棿鍐呮樉绀虹姸鎬�1锛岀劧鍚庣姸鎬佷氦鐣屽璁剧疆棰滆壊娓愬彉锛屽叾浣欏悓鐞嗭紝杩欐牱璺宠浆寰楁椂鍊欒兘澶熺洿鎺ヨ烦杞埌褰撳墠寰楅鑹蹭俊鎭樁娈碉紝鐩存帴搴旂敤锛屽嵆鍙�
+// ============================================================================
 // 鍏ㄥ眬鐘舵�佽褰�
 const colorState = {
-  maxStage: 0, // 璁板綍鍘嗗彶鏈�楂橀樁娈�
-  maxAlpha: -0.3, // 璁板綍鍘嗗彶鏈�灏忛�忔槑搴︼紙璐熷�硷級
-  maxLuminance: 240.4, // 璁板綍鍘嗗彶鏈�浣庝寒搴︼紙瀵瑰簲stage 0鍒濆鍊硷級
   currentColor: "#F5F0E6", // 褰撳墠棰滆壊
+  currentAlpha: -0.3,      // 褰撳墠閫忔槑搴�
+  colorStages: null,       // 棰勮绠楃殑棰滆壊闃舵鏃堕棿鐐�
+  maxColorTime: null       // 璁板綍杈惧埌鏈�娣遍鑹叉椂鐨勬椂闂寸偣
 };
 
-function updateWaterColorByTime() {
+// 棰勮绠楅鑹查樁娈垫椂闂寸偣
+function precomputeColorStages() {
   if (!rainTotalInfo.value || rainTotalInfo.value.length === 0) return;
 
-  // 1. 璁$畻鍩虹鏁版嵁
-  const { intensity, IR } = calculateRainData();
-
-  // 2. 棰滆壊閰嶇疆锛堜寒搴︿弗鏍奸�掑噺锛�
+  // 棰滆壊閰嶇疆锛堜寒搴﹂�掑噺锛�
   const COLOR_STOPS = [
     { hex: "#F5F0E6", luminance: 240.4 }, // stage 0
-    { hex: "#D4F2E7", luminance: 231.8 }, // stage 1
-    { hex: "#E6D5B8", luminance: 214.8 }, // stage 2
-    { hex: "#D4B483", luminance: 184.0 }, // stage 3
-    { hex: "#B78B6A", luminance: 148.4 }, // stage 4
-    { hex: "#8B5A3A", luminance: 101.0 }, // stage 5
-    { hex: "#4A3123", luminance: 54.9 }, // stage 6
-  ];
+    { hex: "#E6D5B8", luminance: 214.8 }, // stage 1
+    { hex: "#D4B483", luminance: 184.0 }, // stage 2
+    { hex: "#B78B6A", luminance: 148.4 }, // stage 3
+    { hex: "#8B5A3A", luminance: 101.0 }, // stage 4
+    { hex: "#744C33", luminance: 84.5 },  // stage 5
+    { hex: "#5D3D2C", luminance: 68.1 }   // stage 6
+];
   const alphaStops = [
-    1 - 0.3, // stage 0
-    -0.4, // stage 1
-    -0.5, // stage 2
-    -0.6, // stage 3
-    -0.7, // stage 4
-    -0.75, // stage 5
-    -0.8, // stage 6
+    -0.3,   // stage 0
+    -0.4,   // stage 1
+    -0.5,   // stage 2
+    -0.6,   // stage 3
+    -0.7,   // stage 4
+    -0.75,  // stage 5
+    -0.8    // stage 6
   ];
-  // 3. 鏇存柊闃舵鐘舵��
-  updateStageState(intensity, IR);
 
-  // 4. 璁$畻骞堕攣瀹氶鑹诧紙纭繚浜害涓嶅洖鍗囷級
-  updateColorState(COLOR_STOPS, intensity, IR);
-
-  // 5. 搴旂敤棰滆壊
-  updateWaterColor(colorState.currentColor, colorState.maxAlpha);
-
-  // --- 杈呭姪鍑芥暟 ---
-  function calculateRainData() {
-    const initialTimestamp = new Date(rainTotalInfo.value[0].time).getTime();
-    const currentTimestamp = new Date(
-      rainTotalInfo.value[
-        Math.min(
-          Math.floor(
-            (currentTime.value / duration.value) *
-              (rainTotalInfo.value.length - 1)
-          ),
-          rainTotalInfo.value.length - 2
-        )
-      ].time
-    ).getTime();
-
-    // 闄嶉洦寮哄害璁$畻锛堝甫鎻掑�硷級
-    const progress = currentTime.value / duration.value;
-    const floatIndex = progress * (rainTotalInfo.value.length - 1);
-    let index = Math.floor(floatIndex);
-    if (index >= rainTotalInfo.value.length - 1) {
-      index = rainTotalInfo.value.length - 2; // 闃叉 index+1 瓒婄晫
-    }
-    const lerpAlpha = floatIndex - index;
-    const intensity =
-      rainTotalInfo.value[index].intensity * (1 - lerpAlpha) +
-      rainTotalInfo.value[index + 1].intensity * lerpAlpha;
-
-    // 涓寸晫闄嶉洦寮哄害璁$畻
-    const D = (currentTimestamp - initialTimestamp) / (1000 * 60 * 60) + 0.0001;
+  // 璁$畻姣忎釜闃舵棣栨杈惧埌鐨勬椂闂寸偣
+  const stages = [];
+  const thresholds = [0, 0.2, 0.4, 0.6, 0.8, 1.0];
+  
+  // 璁$畻姣忎釜鏃堕棿鐐圭殑寮哄害
+  const timeIntensities = [];
+  const initialTimestamp = new Date(rainTotalInfo.value[0].time).getTime();
+  
+  for (let i = 0; i < rainTotalInfo.value.length; i++) {
+    const timestamp = new Date(rainTotalInfo.value[i].time).getTime();
+    const D = (timestamp - initialTimestamp) / (1000 * 60 * 60) + 0.0001;
     const IR = 56.9 * Math.pow(D, -0.746);
-
-    return { intensity, IR };
+    const intensity = rainTotalInfo.value[i].intensity;
+    
+    timeIntensities.push({
+      time: (timestamp - initialTimestamp) / 1000,
+      intensity,
+      IR
+    });
   }
 
-  function updateStageState(intensity, IR) {
-    // 璁$畻鐞嗚闃舵
-    let stage = 0;
-    const thresholds = [0, 0.2, 0.4, 0.6, 0.8, 1.0];
-    for (let i = thresholds.length - 1; i >= 0; i--) {
-      if (intensity >= thresholds[i] * IR) {
-        stage = i + 1;
+  // 鎵惧嚭姣忎釜闃舵棣栨杈惧埌鐨勬椂闂寸偣
+  for (let stage = 1; stage < COLOR_STOPS.length; stage++) {
+    const threshold = thresholds[stage - 1];
+    
+    for (let i = 0; i < timeIntensities.length; i++) {
+      const { time, intensity, IR } = timeIntensities[i];
+      
+      if (intensity >= threshold * IR) {
+        // 鎵惧埌璇ラ樁娈靛紑濮嬫椂闂寸偣
+        stages[stage] = {
+          startTime: time,
+          color: COLOR_STOPS[stage].hex,
+          alpha: alphaStops[stage],
+          threshold: threshold
+        };
         break;
       }
     }
-
-    // 鏇存柊鏈�澶ч樁娈碉紙鍗曞悜閫掑锛�
-    colorState.maxStage = Math.max(colorState.maxStage, stage);
   }
 
-  function updateColorState(colorStops, intensity, IR) {
-    // 宸茶揪鏈�缁堥樁娈�
-    if (colorState.maxStage >= colorStops.length - 1) {
-      colorState.currentColor = colorStops[colorStops.length - 1].hex;
-      colorState.maxAlpha = -0.8;
-      colorState.maxLuminance = colorStops[colorStops.length - 1].luminance;
-      return;
-    }
+  // 濉厖闃舵0
+  stages[0] = {
+    startTime: 0,
+    color: COLOR_STOPS[0].hex,
+    alpha: alphaStops[0],
+    threshold: 0
+  };
 
-    // 璁$畻褰撳墠闃舵杩涘害
-    const stageThresholds = [0, 0.2, 0.4, 0.6, 0.8, 1.0];
-    const lowerThreshold = stageThresholds[colorState.maxStage - 1] * IR;
-    const upperThreshold = stageThresholds[colorState.maxStage] * IR;
-    const ratio = Math.min(
-      1,
-      Math.max(
-        0,
-        (intensity - lowerThreshold) / (upperThreshold - lowerThreshold)
-      )
-    );
-
-    // 棰滆壊鎻掑��
-    const startColor = colorStops[colorState.maxStage];
-    const endColor = colorStops[colorState.maxStage + 1];
-    const newColor = lerpColor(startColor.hex, endColor.hex, ratio);
-    const newLuminance = calculateLuminance(newColor);
-
-    // 鍙帴鍙楁洿鏆楃殑棰滆壊锛堜寒搴︽洿浣庯級
-    if (newLuminance < colorState.maxLuminance) {
-      colorState.currentColor = newColor;
-      colorState.maxLuminance = newLuminance;
-      colorState.maxAlpha = Math.min(
-        colorState.maxAlpha,
-        lerp(
-          alphaStops[colorState.maxStage],
-          alphaStops[colorState.maxStage + 1],
-          ratio
-        )
-      );
-    }
-
-    console.log(
-      `闃舵: ${colorState.maxStage} | 浜害: ${colorState.maxLuminance.toFixed(
-        1
-      )} | 棰滆壊: ${colorState.currentColor}`
-    );
-  }
-
-  // 棰滆壊鎻掑�煎伐鍏峰嚱鏁�
-  function lerpColor(c1, c2, t) {
-    const [r1, g1, b1] = hexToRgb(c1);
-    const [r2, g2, b2] = hexToRgb(c2);
-    return rgbToHex(r1 + (r2 - r1) * t, g1 + (g2 - g1) * t, b1 + (b2 - b1) * t);
-  }
-
-  function calculateLuminance(hex) {
-    const [r, g, b] = hexToRgb(hex);
-    return 0.299 * r + 0.587 * g + 0.114 * b;
-  }
-
-  function hexToRgb(hex) {
-    const bigint = parseInt(hex.slice(1), 16);
-    return [(bigint >> 16) & 255, (bigint >> 8) & 255, bigint & 255];
-  }
-
-  function rgbToHex(r, g, b) {
-    return `#${[r, g, b]
-      .map((x) => Math.round(x).toString(16).padStart(2, "0"))
-      .join("")}`;
-  }
-
-  function lerp(a, b, t) {
-    return a + (b - a) * t;
-  }
+  colorState.colorStages = stages;
 }
+
+function updateWaterColorByTime(isForceUpdate = false) {
+  if (!rainTotalInfo.value || rainTotalInfo.value.length === 0) return;
+  
+  // 棣栨璋冪敤鏃堕璁$畻棰滆壊闃舵
+  if (colorState.colorStages === null) {
+    precomputeColorStages();
+  }
+
+  // 鏌ユ壘褰撳墠鏃堕棿鐐规墍灞炵殑闃舵
+  let currentStage = 0;
+  for (let i = colorState.colorStages.length - 1; i >= 0; i--) {
+    if (colorState.colorStages[i] && currentTime.value >= colorState.colorStages[i].startTime) {
+      currentStage = i;
+      break;
+    }
+  }
+
+  // 璁板綍杈惧埌鏈�娣遍鑹茬殑鏃堕棿鐐�
+  if (currentStage >= colorState.colorStages.length - 1) {
+    if (colorState.maxColorTime === null || currentTime.value > colorState.maxColorTime) {
+      colorState.maxColorTime = currentTime.value;
+    }
+  }
+
+  // 鍒ゆ柇鏄惁闇�瑕佸己鍒舵洿鏂伴鑹�
+  const isTimeGoingBackward = currentTime.value < colorState.lastTime;
+  const isBeforeMaxColorTime = colorState.maxColorTime !== null && currentTime.value <= colorState.maxColorTime;
+  const shouldForceUpdate = isForceUpdate && (isTimeGoingBackward || isBeforeMaxColorTime);
+
+  // 鏇存柊棰滆壊閫昏緫
+  if (shouldForceUpdate || isTimeGoingBackward) {
+    // 寮哄埗鏇存柊鎴栨椂闂村洖閫�鏃讹紝鐩存帴搴旂敤褰撳墠闃舵鐨勯鑹�
+    colorState.currentColor = colorState.colorStages[currentStage].color;
+    colorState.currentAlpha = colorState.colorStages[currentStage].alpha;
+  } else {
+    // 姝e父鏃堕棿鍓嶈繘鏃讹紝淇濇寔娓愯繘鍙樺寲
+    const newColor = colorState.colorStages[currentStage].color;
+    const newAlpha = colorState.colorStages[currentStage].alpha;
+    
+    // 鍙簲鐢ㄦ洿鏆楃殑棰滆壊鍜屾洿浣庣殑閫忔槑搴�
+    if (calculateLuminance(newColor) < calculateLuminance(colorState.currentColor)) {
+      colorState.currentColor = newColor;
+    }
+    if (newAlpha < colorState.currentAlpha) {
+      colorState.currentAlpha = newAlpha;
+    }
+  }
+
+  // 鏇存柊鏃堕棿璁板綍
+  colorState.lastTime = currentTime.value;
+
+  // 搴旂敤棰滆壊
+  updateWaterColor(colorState.currentColor, colorState.currentAlpha);
+}
+
+// 杈呭姪鍑芥暟淇濇寔涓嶅彉
+function calculateLuminance(hex) {
+  const [r, g, b] = hexToRgb(hex);
+  return 0.299 * r + 0.587 * g + 0.114 * b;
+}
+
+function hexToRgb(hex) {
+  const bigint = parseInt(hex.slice(1), 16);
+  return [(bigint >> 16) & 255, (bigint >> 8) & 255, bigint & 255];
+}
+
+// 鏃堕棿杞磋烦杞嚱鏁�
+const seekToPosition = (event) => {
+  if (!isWaterPrimitiveCreated.value) {
+    ElMessage.warning("璇峰厛鍚姩姘翠綋妯℃嫙鍚庡啀杩涜鏃堕棿杞磋烦杞��");
+    return;
+  }
+
+  const rect = timelineTrack.value.getBoundingClientRect();
+  const percentage = (event.clientX - rect.left) / rect.width;
+  const targetTime = Math.round(percentage * duration.value);
+
+  const closestIndex = findClosestTimestampIndex(targetTime);
+  const baseTimestamp = waterTimestamps.value[0];
+  const newTime = (waterTimestamps.value[closestIndex] - baseTimestamp) / 1000;
+  
+  // 鍒ゆ柇鏄惁闇�瑕佸己鍒舵洿鏂伴鑹�
+  const isGoingBackward = newTime < currentTime.value;
+  const isBeforeMaxColor = colorState.maxColorTime !== null && newTime <= colorState.maxColorTime;
+  const shouldForceUpdate = isGoingBackward || isBeforeMaxColor;
+  
+  currentTime.value = newTime;
+  setTimeForWaterSimulation(closestIndex);
+  
+  // 鏍规嵁鏉′欢鏇存柊棰滆壊
+  updateWaterColorByTime(shouldForceUpdate);
+  
+  if (!isPlaying.value) pauseWaterSimulation();
+};
+// ============================================================================
 
 function updateWeatherByProgress() {
   if (rainFallValues.value.length === 0) return;
@@ -802,27 +818,7 @@
   EventBus.emit("clear-echart");
   EventBus.emit("reset-table");
 };
-// 鏃堕棿杞磋烦杞�
-const seekToPosition = (event) => {
-  if (!isWaterPrimitiveCreated.value) {
-    ElMessage.warning("璇峰厛鍚姩姘翠綋妯℃嫙鍚庡啀杩涜鏃堕棿杞磋烦杞��");
-    return;
-  }
 
-  const rect = timelineTrack.value.getBoundingClientRect();
-  const percentage = (event.clientX - rect.left) / rect.width;
-  const targetTime = Math.round(percentage * duration.value);
-
-  // 鐩存帴鎵惧埌鏈�杩戠殑 timestamp 绱㈠紩
-  const closestIndex = findClosestTimestampIndex(targetTime);
-  const baseTimestamp = waterTimestamps.value[0];
-  currentTime.value =
-    (waterTimestamps.value[closestIndex] - baseTimestamp) / 1000;
-
-  // 鏇存柊姘翠綋妯℃嫙鏃堕棿
-  setTimeForWaterSimulation(closestIndex);
-  if (!isPlaying.value) pauseWaterSimulation();
-};
 // 杈呭姪鍑芥暟锛氭壘鍒版渶鎺ヨ繎鐨勬椂闂存埑绱㈠紩
 function findClosestTimestampIndex(currentTimeValue) {
   if (waterTimestamps.value.length === 0) return 0;
diff --git a/src/utils/water.js b/src/utils/water.js
index e784d23..a58bd68 100644
--- a/src/utils/water.js
+++ b/src/utils/water.js
@@ -92,7 +92,7 @@
     colorRender,
     sizeIndex: 0,
   });
-  // enableWaterArrowFlow(false);
+  enableWaterArrowFlow(false);
   toggleWaterShadow(false);
   // console.log(
   //   `浠跨湡妯℃嫙鍙傛暟锛氳姹傝矾寰� ${baseUrl}, 甯ч棿闂撮殧 ${interval}ms, 鏄惁寮�鍚笓棰樻覆鏌� ${colorRender}`

--
Gitblit v1.9.3