基于光标移动的元素(div/组件等)过渡动画实现方法咨询
实现基于光标距离的元素颜色过渡效果
嘿,这个交互效果超有氛围感!我之前做过类似的需求,核心就是实时追踪鼠标位置,计算光标到目标元素的距离,再根据距离动态插值元素样式。下面我给你一个完整的可运行示例,一步一步拆解怎么实现:
核心思路
- 监听页面的
mousemove事件,拿到鼠标的实时坐标 - 计算光标到目标元素中心的直线距离(用勾股定理就行)
- 设定一个「影响范围半径」:当光标在这个半径内时,根据距离占半径的比例,从原色过渡到目标色;超出半径就恢复原色
- 用CSS变量或者直接修改元素的
background-color来应用动态颜色
完整代码示例
HTML
<div class="box blue-box"></div> <div class="box red-box"></div>
CSS
body { margin: 0; height: 100vh; position: relative; overflow: hidden; } .box { width: 150px; height: 150px; position: absolute; transition: background-color 0.1s ease; /* 加个过渡让颜色变化更丝滑 */ } .blue-box { bottom: 20px; left: 20px; background-color: #007bff; /* 初始蓝色 */ } .red-box { bottom: 20px; right: 20px; background-color: #dc3545; /* 初始红色 */ }
JavaScript
// 获取目标元素 const blueBox = document.querySelector('.blue-box'); const redBox = document.querySelector('.red-box'); // 设定影响半径(可以根据需求调整,比如200px) const influenceRadius = 200; // 计算元素中心坐标的工具函数 function getElementCenter(el) { const rect = el.getBoundingClientRect(); return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 }; } // 颜色插值工具函数:根据比例从color1过渡到color2 function interpolateColor(color1, color2, ratio) { // 把十六进制颜色转成RGB数组 const 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]; }; const [r1, g1, b1] = hexToRgb(color1); const [r2, g2, b2] = hexToRgb(color2); // 计算插值后的RGB值 const r = Math.round(r1 + ratio * (r2 - r1)); const g = Math.round(g1 + ratio * (g2 - g1)); const b = Math.round(b1 + ratio * (b2 - b1)); return `rgb(${r}, ${g}, ${b})`; } // 鼠标移动事件处理函数 function handleMouseMove(e) { // 处理蓝色盒子:从蓝色过渡到绿色 const blueCenter = getElementCenter(blueBox); // 计算光标到盒子中心的距离 const distanceToBlue = Math.sqrt( Math.pow(e.clientX - blueCenter.x, 2) + Math.pow(e.clientY - blueCenter.y, 2) ); // 计算过渡比例:距离越近,比例越接近1(完全变成绿色) const blueRatio = Math.max(0, Math.min(1, 1 - distanceToBlue / influenceRadius)); blueBox.style.backgroundColor = interpolateColor('#007bff', '#28a745', blueRatio); // 处理红色盒子:示例从红色过渡到黄色,你可以随便改目标色 const redCenter = getElementCenter(redBox); const distanceToRed = Math.sqrt( Math.pow(e.clientX - redCenter.x, 2) + Math.pow(e.clientY - redCenter.y, 2) ); const redRatio = Math.max(0, Math.min(1, 1 - distanceToRed / influenceRadius)); redBox.style.backgroundColor = interpolateColor('#dc3545', '#ffc107', redRatio); } // 绑定事件 document.addEventListener('mousemove', handleMouseMove);
扩展玩法
- 如果想要其他过渡效果(比如元素大小、透明度),只需要把修改
background-color的部分换成修改transform: scale()或者opacity就行,逻辑完全一致 - 可以给不同元素设置不同的影响半径,让交互更有层次感
- 要是觉得
mousemove事件触发太频繁影响性能,可以用requestAnimationFrame来节流优化事件处理
内容的提问来源于stack exchange,提问作者mayo19
相关产品推荐
相关产品推荐

