鼠标移动时页面背景渐变切换闪烁问题求助
解决渐变随机切换时的闪烁问题
看起来你遇到的闪烁问题,核心原因是每次鼠标移动事件触发时,你都随机从数组里选了一个新的起始颜色,这导致渐变的起始色没有任何过渡就直接跳变,视觉上就会出现闪烁。当只有2种颜色时,切换频率低或者颜色差异小,所以没那么明显,但4种颜色随机选的话,跳变就会很频繁,闪烁感就出来了。
下面给你几个可行的解决方案:
方案1:预定义渐变并使用CSS过渡平滑切换
首先,把所有从目标色到白色的渐变都预定义成CSS类,然后通过切换类名,并给background属性加上过渡效果,让渐变切换更平滑:
/* 预定义所有渐变类 */ .grad-1 { background: linear-gradient(var(--angle), #dfa7ca, #fff); } .grad-2 { background: linear-gradient(var(--angle), #f7c2b3, #fff); } .grad-3 { background: linear-gradient(var(--angle), #bae0f1, #fff); } .grad-4 { background: linear-gradient(var(--angle), #a6d6cb, #fff); } /* 给背景添加过渡,让切换平滑 */ body { transition: background 0.3s ease; --angle: 0deg; }
然后JS部分,不要每次鼠标移动都随机选,而是设置一个切换间隔,或者在鼠标移动时只更新角度,每隔一段时间再随机切换渐变类:
const colorArr = ['grad-1', 'grad-2', 'grad-3', 'grad-4']; const body = document.body; let currentClass = colorArr[0]; let lastSwitchTime = Date.now(); // 鼠标移动时更新渐变角度 body.addEventListener('mousemove', (e) => { const angle = (e.clientX / window.innerWidth) * 360; body.style.setProperty('--angle', `${angle}deg`); // 每隔1秒才随机切换一次渐变(可调整间隔) const now = Date.now(); if (now - lastSwitchTime > 1000) { let newClass; // 避免重复选当前类 do { newClass = colorArr[Math.floor(Math.random() * colorArr.length)]; } while (newClass === currentClass); body.classList.remove(currentClass); body.classList.add(newClass); currentClass = newClass; lastSwitchTime = now; } });
方案2:直接用JS控制渐变的平滑过渡
如果你不想用预定义类,可以通过计算颜色的过渡值,让每次切换时从当前颜色平滑过渡到下一个随机颜色,而不是直接跳变:
const colorArr = ['#dfa7ca', '#f7c2b3', '#bae0f1', '#a6d6cb']; const body = document.body; let currentColor = colorArr[0]; let targetColor = currentColor; let transitionProgress = 1; let lastSwitchTime = Date.now(); // 颜色转RGB对象的工具函数 function hexToRgb(hex) { const r = parseInt(hex.slice(1, 3), 16); const g = parseInt(hex.slice(3, 5), 16); const b = parseInt(hex.slice(5, 7), 16); return { r, g, b }; } // 混合两个颜色的工具函数 function mixColors(color1, color2, progress) { const rgb1 = hexToRgb(color1); const rgb2 = hexToRgb(color2); const r = Math.round(rgb1.r + (rgb2.r - rgb1.r) * progress); const g = Math.round(rgb1.g + (rgb2.g - rgb1.g) * progress); const b = Math.round(rgb1.b + (rgb2.b - rgb1.b) * progress); return `rgb(${r}, ${g}, ${b})`; } // 更新渐变的函数 function updateGradient(e) { const angle = (e.clientX / window.innerWidth) * 360; // 处理颜色过渡 if (transitionProgress < 1) { transitionProgress += 0.02; // 调整过渡速度 const mixedColor = mixColors(currentColor, targetColor, transitionProgress); body.style.background = `linear-gradient(${angle}deg, ${mixedColor}, #fff)`; } else { // 每隔一段时间切换目标颜色 const now = Date.now(); if (now - lastSwitchTime > 1500) { let newColor; do { newColor = colorArr[Math.floor(Math.random() * colorArr.length)]; } while (newColor === currentColor); targetColor = newColor; currentColor = body.style.background.match(/rgb\((.*?)\)/)[0]; // 获取当前显示的颜色 transitionProgress = 0; lastSwitchTime = now; } body.style.background = `linear-gradient(${angle}deg, ${currentColor}, #fff)`; } } body.addEventListener('mousemove', updateGradient);
关键注意点
- 避免每次鼠标移动都随机切换起始色,因为鼠标移动事件触发频率极高(每秒几十次),频繁的颜色跳变必然导致闪烁。
- 给渐变变化加上过渡动画,无论是用CSS的
transition还是JS手动计算颜色过渡,都能让视觉变化更平滑。 - 如果要随机切换颜色,记得设置切换间隔,不要太频繁,同时避免重复选当前颜色,减少不必要的变化。
内容的提问来源于stack exchange,提问作者mjpramos
相关产品推荐
相关产品推荐

