From 92254cb750d070923337283e23a205bccc446415 Mon Sep 17 00:00:00 2001 From: LOG1997 <2694233102@qq.com> Date: Tue, 16 Dec 2025 23:36:44 +0800 Subject: [PATCH] =?UTF-8?q?fix(home):=20=F0=9F=90=9B=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E5=A4=9A=E6=AC=A1=E5=88=87=E6=8D=A2=E8=B7=AF=E7=94=B1=E5=90=8E?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=8D=A1=E9=A1=BF=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20#96=20(#119)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 卸载路由时清除requestAnimationFrame --- src/utils/color.ts | 90 +++++++++++++++++----------------- src/views/Home/useViewModel.ts | 10 +++- 2 files changed, 55 insertions(+), 45 deletions(-) diff --git a/src/utils/color.ts b/src/utils/color.ts index dd7f7dc..0348f76 100644 --- a/src/utils/color.ts +++ b/src/utils/color.ts @@ -1,71 +1,73 @@ // 判断颜色是否rgb或者rgba export function isRgbOrRgba(color: string) { - return color.includes('rgb') || color.includes('rgba') + return color.includes('rgb') || color.includes('rgba') } // 判断是否hex形式 export function isHex(color: string) { - return color.includes('#') + return color.includes('#') } // 把hex颜色转成rgb数值类型 export function hexToRgba(hex: string) { - const r = Number.parseInt(hex.slice(1, 3), 16) - const g = Number.parseInt(hex.slice(3, 5), 16) - const b = Number.parseInt(hex.slice(5, 7), 16) + const r = Number.parseInt(hex.slice(1, 3), 16) + const g = Number.parseInt(hex.slice(3, 5), 16) + const b = Number.parseInt(hex.slice(5, 7), 16) - return { r, g, b } + return { r, g, b } } // 把rgb数组转化成r g b 数值 export function rgbToRgba(rgb: string) { - const rgbArr = rgb.split('(')[1].split(')')[0].split(',') + const rgbArr = rgb.split('(')[1].split(')')[0].split(',') - return { r: rgbArr[0], g: rgbArr[1], b: rgbArr[2] } + return { r: rgbArr[0], g: rgbArr[1], b: rgbArr[2] } } // 组成rgb颜色添加透明度 export function rgba(color: string, opacity: number) { - opacity = opacity || 1 - let rgbaStr = '' - // 判断是否是hex颜色 - if (isHex(color)) { - const { r, g, b } = hexToRgba(color) - rgbaStr = `rgba(${r},${g},${b},${opacity})` - } - else { - const { r, g, b } = rgbToRgba(color) - rgbaStr = `rgba(${r},${g},${b},${opacity})` - } + opacity = opacity || 1 + let rgbaStr = '' + // 判断是否是hex颜色 + if (isHex(color)) { + const { r, g, b } = hexToRgba(color) + rgbaStr = `rgba(${r},${g},${b},${opacity})` + } + else { + const { r, g, b } = rgbToRgba(color) + rgbaStr = `rgba(${r},${g},${b},${opacity})` + } - return rgbaStr + return rgbaStr } -export function rgbToHex(color:string) { - // 去掉字符串中的空格 - color = color.replace(/\s+/g, ''); +export function rgbToHex(color: string) { + // 去掉字符串中的空格 + color = color.replace(/\s+/g, ''); + if (isHex(color)) { + return color + } + // 匹配rgba或rgb格式的字符串 + const rgbaMatch = color.match(/^rgba?\((\d+),(\d+),(\d+),?(\d*\.?\d+)?\)$/i); + if (!rgbaMatch) { + throw new Error('Invalid color format'); + } - // 匹配rgba或rgb格式的字符串 - const rgbaMatch = color.match(/^rgba?\((\d+),(\d+),(\d+),?(\d*\.?\d+)?\)$/i); - if (!rgbaMatch) { - throw new Error('Invalid color format'); - } + const r = parseInt(rgbaMatch[1], 10); + const g = parseInt(rgbaMatch[2], 10); + const b = parseInt(rgbaMatch[3], 10); + const a = rgbaMatch[4] !== undefined ? parseFloat(rgbaMatch[4]) : undefined; - const r = parseInt(rgbaMatch[1], 10); - const g = parseInt(rgbaMatch[2], 10); - const b = parseInt(rgbaMatch[3], 10); - const a = rgbaMatch[4] !== undefined ? parseFloat(rgbaMatch[4]) : undefined; + // 将RGB值转换为十六进制 + let hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase(); - // 将RGB值转换为十六进制 - let hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase(); + // 如果提供了alpha值,则将其转换为十六进制并附加到结果中 + if (a !== undefined) { + let alphaHex = Math.round(a * 255).toString(16).toUpperCase(); + if (alphaHex.length === 1) { + alphaHex = "0" + alphaHex; // 确保alpha值是两位数 + } + hex += alphaHex; + } - // 如果提供了alpha值,则将其转换为十六进制并附加到结果中 - if (a !== undefined) { - let alphaHex = Math.round(a * 255).toString(16).toUpperCase(); - if (alphaHex.length === 1) { - alphaHex = "0" + alphaHex; // 确保alpha值是两位数 - } - hex += alphaHex; - } - - return hex; + return hex; } \ No newline at end of file diff --git a/src/views/Home/useViewModel.ts b/src/views/Home/useViewModel.ts index b627ae1..fb27f80 100644 --- a/src/views/Home/useViewModel.ts +++ b/src/views/Home/useViewModel.ts @@ -52,6 +52,7 @@ export function useViewModel() { const personPool = ref([]) const intervalTimer = ref(null) const isInitialDone = ref(false) + const animationFrameId = ref(null) function initThreeJs() { const felidView = 40 @@ -214,7 +215,7 @@ export function useViewModel() { } // 设置自动旋转 // 设置相机位置 - requestAnimationFrame(animation) + animationFrameId.value = requestAnimationFrame(animation) } /** * @description: 旋转的动画 @@ -531,6 +532,13 @@ export function useViewModel() { * @description: 清理资源,避免内存溢出 */ function cleanup() { + // 停止所有Tween动画 + TWEEN.removeAll() + + // 清理动画循环 + if ((window as any).cancelAnimationFrame) { + (window as any).cancelAnimationFrame(animationFrameId.value) + } clearInterval(intervalTimer.value) intervalTimer.value = null if (scene.value) {