From fcb7d9aad38db5263426e3255ab88604ec60d8ca Mon Sep 17 00:00:00 2001 From: wangjuncheng <1> Date: 星期一, 30 六月 2025 10:17:56 +0800 Subject: [PATCH] 修改颜色 --- src/components/menu/TimeLine.vue | 324 ++++++++++++++++++++++++++--------------------------- 1 files changed, 160 insertions(+), 164 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; -- Gitblit v1.9.3