如何用原生JS实现稳定的transform3D鼠标追踪倾斜及闪光灯效果?
实现鼠标追踪的3D变换与闪光灯效果

要实现如图所示的交互效果,我们可以用原生JavaScript完成,核心包含区块3D旋转追踪和鼠标位置闪光两部分,以下是具体实现方案:
核心逻辑拆解
1. 3D旋转角度控制
要让旋转角度稳定在-8°到9°之间,需要将鼠标在元素内的相对位置线性映射到目标角度范围:
- 先获取鼠标在元素内部的坐标(相对于元素左上角)
- 将坐标转换为0~1的比例值(0对应元素边缘,1对应对边)
- 通过公式将比例映射到角度:
- 对于
rotateY(左右旋转):(比例X - 0.5) * 2 * 最大Y角度,0.5对应元素中心,以此实现中心为0角度的对称旋转 - 对于
rotateX(上下旋转):(0.5 - 比例Y) * 2 * 最大X角度,反转Y轴方向让旋转符合视觉直觉
- 对于
2. 闪光灯效果
通过动态创建临时元素,配合CSS动画实现闪烁:
- 鼠标移动时在对应位置生成圆形闪光元素
- 利用CSS动画让闪光从透明小圆圈扩散消失
- 动画结束后自动移除元素,避免DOM冗余
完整代码实现
HTML
<div class="container"> <div class="blockwrapper"> <div class="block moved">Moved</div> </div> <div id="p1" class="blockwrapper"> <div class="block">Movable</div> </div> </div>
CSS
.container { padding: 40px; } .blockwrapper { position: relative; will-change: transform; transform: translate3d(0, 0, 0) rotateX(0deg) rotateY(0deg); transition: transform 0.1s ease-out; /* 平滑过渡提升视觉体验 */ margin: 10px; display: inline-block; } .block { background-color: skyblue; width: 160px; height: 160px; } .moved { background-color: pink; } /* 闪光动画样式 */ .flash { position: absolute; width: 40px; height: 40px; border-radius: 50%; background: rgba(255, 255, 255, 0.8); pointer-events: none; transform: translate(-50%, -50%) scale(0); animation: flash 0.5s forwards; } @keyframes flash { to { opacity: 0; transform: translate(-50%, -50%) scale(2); } }
JavaScript
const targetElement = document.getElementById('p1'); const maxRotateX = 8; // X轴旋转最大角度(正负范围) const maxRotateY = 9; // Y轴旋转最大角度(正负范围) /** * 设置元素3D变换 */ function applyTransform(rotateX, rotateY, element) { element.style.transform = `translate3d(0, 0, 0) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; } /** * 创建鼠标位置闪光效果 */ function createFlashEffect(x, y) { const flash = document.createElement('div'); flash.classList.add('flash'); flash.style.left = `${x}px`; flash.style.top = `${y}px`; targetElement.appendChild(flash); // 动画结束后移除元素 flash.addEventListener('animationend', () => flash.remove()); } // 鼠标移动监听 targetElement.addEventListener('mousemove', (event) => { const elementRect = targetElement.getBoundingClientRect(); // 计算鼠标在元素内的相对坐标 const relativeX = event.clientX - elementRect.left; const relativeY = event.clientY - elementRect.top; // 转换为0~1的比例值 const xRatio = relativeX / elementRect.width; const yRatio = relativeY / elementRect.height; // 映射到目标角度范围 const rotateY = (xRatio - 0.5) * 2 * maxRotateY; const rotateX = (0.5 - yRatio) * 2 * maxRotateX; // 应用变换 applyTransform(rotateX, rotateY, targetElement); // 创建闪光效果 createFlashEffect(relativeX, relativeY); }); // 鼠标离开重置变换 targetElement.addEventListener('mouseleave', () => { applyTransform(0, 0, targetElement); });
内容的提问来源于stack exchange,提问作者The Old County
相关产品推荐
相关产品推荐

